如何使用Bokeh(或其他库)在python中制作轮廓图?

dsa*_*laj 3 python plot contour bokeh

我有兴趣在Bokeh制作等高线图.到目前为止,我还没能在网上找到任何东西.

提醒一下,这是轮廓图:

在此输入图像描述

任何帮助,将不胜感激.我也欢迎其他图书馆的建议,但前提条件是允许交互式/动画图,而不仅仅是渲染静态输出(图像).

小智 5

过去一年,Plotly 支持 Python 中的等高线图:

https://plot.ly/python/contour-plots/

https://plot.ly/pandas/contour-plots/

密度图(具有相邻直方图的等值线图):

https://plot.ly/python/2d-density-plots/

https://plot.ly/pandas/2d-density-plots/

Plotly Python 库位于 pip 上,100% 免费且开源。

蟒蛇轮廓图


小智 5

您还可以使用matplotlibs等高线图计算等高线数据,然后使用bokehs multi_line绘制等高线。我也在绘制文本标签(不幸的是这有点丑陋)。

import numpy as np
import matplotlib.pyplot as plt
from bokeh.models import ColumnDataSource
from bokeh.io import output_file
from bokeh.plotting import gridplot,figure, show

def get_contour_data(X, Y, Z):
    cs = plt.contour(X, Y, Z)
    xs = []
    ys = []
    xt = []
    yt = []
    col = []
    text = []
    isolevelid = 0
    for isolevel in cs.collections:
        isocol = isolevel.get_color()[0]
        thecol = 3 * [None]
        theiso = str(cs.get_array()[isolevelid])
        isolevelid += 1
        for i in range(3):
            thecol[i] = int(255 * isocol[i])
        thecol = '#%02x%02x%02x' % (thecol[0], thecol[1], thecol[2])

        for path in isolevel.get_paths():
            v = path.vertices
            x = v[:, 0]
            y = v[:, 1]
            xs.append(x.tolist())
            ys.append(y.tolist())
            xt.append(x[len(x) / 2])
            yt.append(y[len(y) / 2])
            text.append(theiso)
            col.append(thecol)

    source = ColumnDataSource(data={'xs': xs, 'ys': ys, 'line_color': col,'xt':xt,'yt':yt,'text':text})
    return source


output_file("contour.html")

N = 400
x = np.linspace(-1, 1, N)
y = np.linspace(-1, 1, N)
X, Y = np.meshgrid(x, y)
Z = X**2 + Y**2

source = get_contour_data(X,Y,Z)
plot = figure(plot_width=400,plot_height=400,x_range=[-1,1], y_range=[-1,1])
plot.multi_line(xs='xs', ys='ys', line_color='line_color', source=source)
plot.text(x='xt',y='yt',text='text',source=source,text_baseline='middle',text_align='center')
show(plot)
Run Code Online (Sandbox Code Playgroud)

这是输出:

在此处输入图片说明


小智 5

我写了一个基于matplotlib输出的填充轮廓工具:

https://github.com/asher-pembroke/bokeh-tools


Dus*_*ell 5

谢谢巴勃罗,你的回答对我很有帮助。

使用您的示例,我制作了一个类似的图,该图使用 skimage 库添加了等高线。我还您引用的散景图像示例一样打开了悬停工具。希望其他人出现并添加线标签。

请注意,以下代码旨在在 Jupyter Notebook 中运行。

from skimage import measure
import numpy as np

from bokeh.plotting import figure, show, output_notebook
from bokeh.models import (ColorBar,
                          FixedTicker, 
                          LinearColorMapper, 
                          PrintfTickFormatter)

output_notebook()

N = 500
x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = np.sin(xx)*np.cos(yy)

mapper = LinearColorMapper(palette='Spectral11', low=-1, high=1)

p = figure(x_range=(0, 10), y_range=(0, 10),
           tooltips=[("x", "$x"), ("y", "$y"), ("value", "@image")])

# must give a vector of image data for image parameter
p.image(image=[d], x=0, y=0, dw=10, dh=10, palette='Spectral11')

levels = np.linspace(-1, 1, 12)
color_bar = ColorBar(color_mapper=mapper, 
                     major_label_text_font_size="8pt",
                     ticker=FixedTicker(ticks=levels),
                     formatter=PrintfTickFormatter(format='%.2f'),
                     label_standoff=6, 
                     border_line_color=None, 
                     location=(0, 0))

p.add_layout(color_bar, 'right')

for level in levels:
  contours = measure.find_contours(d, level)
  for contour in contours:
    x = contour[:,1]/50
    y = contour[:,0]/50
    p.line(x, y, color='grey', line_width=2)

show(p)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明