如何使用Bokeh(或其他库)在python中制作等高线图?

时间:2021-09-16 00:14:31

I am interested in making a contour plot in Bokeh. I have not been able to find anything on the net so far.

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

As a reminder, this is contour plot:

提醒一下,这是轮廓图:

如何使用Bokeh(或其他库)在python中制作等高线图?

Any help would be appreciated. I would also welcome suggestions to other libraries but with prerequisite of allowing for interactive/animated plots, and not only rendering static output (images).

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

4 个解决方案

#1


2  

Plotly has supported contour plots in Python for the past year:

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

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

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

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

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

Density plots (contour plots with adjacent histograms):

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

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

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

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

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

The Plotly Python library is on pip, 100% free and open-source.

Plotly Python库是pip,100%免费和开源。

如何使用Bokeh(或其他库)在python中制作等高线图?

#2


5  

I wrote a filled contour tool based on matplotlib output:

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

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

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

#3


4  

You can also use matplotlibs contour plot for calculation of the contour data and then plot the contours using bokehs multi_line. I'm also plotting text labels (which are unfortunately a bit ugly).

您还可以使用matplotlibs等高线图来计算轮廓数据,然后使用散景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)

this is the output:

这是输出:

如何使用Bokeh(或其他库)在python中制作等高线图?

#4


2  

By choosing a palette with 10 values, like in the example you provide, one can use image (see Bokeh image example) in bokeh to simulate a contour plot. The black contour lines and the numbers are missing, but the boundaries between the colors are actually the contour lines. Also, as far as I know Bokeh does not provide a color bar, but you can code it as another image (UPDATE: Latests versions of Bokeh do provide colorbar. ):

通过选择具有10个值的调色板,如您提供的示例,可以使用散景图像(请参见散景图像示例)来模拟等高线图。黑色轮廓线和数字缺失,但颜色之间的边界实际上是轮廓线。此外,据我所知,Bokeh不提供颜色条,但您可以将其编码为另一个图像(更新:Bokeh的Latests版本确实提供了colorbar。):

from bokeh.io import output_file
from bokeh.plotting import gridplot,figure, show
from bokeh.models import ColumnDataSource,FixedTicker
import numpy as np
from matplotlib import cm,colors

output_file("contour.html")
cmap = cm.get_cmap("jet") #choose any matplotlib colormap here
num_slabs = 10 # number of color steps
jet_10 = [colors.rgb2hex(m) for m in cmap(np.arange(0,cmap.N,cmap.N/(num_slabs-1)))]
vmin = 0
vmax = 1550
N = 200
x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = vmax * (1. + np.sin(xx)*np.cos(yy))

source = ColumnDataSource(data={'d': [d], 'xx': [x], 'yy': [y]})
p = figure(plot_width=400,plot_height=400,x_range=[0, 10], y_range=[0, 10],min_border_right=10)
p.image(image="d", x=[0], y=[0], dw=[10], dh=[10], palette=jet_10,source=source)

# The following code is for the colorbar:
pcb = figure(plot_width=80,plot_height=400,x_range=[0, 1], y_range=[0, vmax],min_border_right=10)
pcb.image(image=[np.linspace(vmin,vmax,100).reshape(100,1)],x=[0],y=[0],dw=[1],dh=[vmax-vmin], palette=jet_10)
pcb.xaxis.major_label_text_color = None
pcb.xaxis.major_tick_line_color = None
pcb.xaxis.minor_tick_line_color = None
pcb.yaxis[0].ticker=FixedTicker(ticks=np.linspace(vmin,vmax,num_slabs+1)) # 11 ticks
pgrid = gridplot([[p,pcb]])  # this places the colorbar next to the image
show(pgrid)

The output will look like: 如何使用Bokeh(或其他库)在python中制作等高线图?

输出看起来像:

#1


2  

Plotly has supported contour plots in Python for the past year:

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

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

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

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

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

Density plots (contour plots with adjacent histograms):

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

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

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

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

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

The Plotly Python library is on pip, 100% free and open-source.

Plotly Python库是pip,100%免费和开源。

如何使用Bokeh(或其他库)在python中制作等高线图?

#2


5  

I wrote a filled contour tool based on matplotlib output:

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

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

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

#3


4  

You can also use matplotlibs contour plot for calculation of the contour data and then plot the contours using bokehs multi_line. I'm also plotting text labels (which are unfortunately a bit ugly).

您还可以使用matplotlibs等高线图来计算轮廓数据,然后使用散景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)

this is the output:

这是输出:

如何使用Bokeh(或其他库)在python中制作等高线图?

#4


2  

By choosing a palette with 10 values, like in the example you provide, one can use image (see Bokeh image example) in bokeh to simulate a contour plot. The black contour lines and the numbers are missing, but the boundaries between the colors are actually the contour lines. Also, as far as I know Bokeh does not provide a color bar, but you can code it as another image (UPDATE: Latests versions of Bokeh do provide colorbar. ):

通过选择具有10个值的调色板,如您提供的示例,可以使用散景图像(请参见散景图像示例)来模拟等高线图。黑色轮廓线和数字缺失,但颜色之间的边界实际上是轮廓线。此外,据我所知,Bokeh不提供颜色条,但您可以将其编码为另一个图像(更新:Bokeh的Latests版本确实提供了colorbar。):

from bokeh.io import output_file
from bokeh.plotting import gridplot,figure, show
from bokeh.models import ColumnDataSource,FixedTicker
import numpy as np
from matplotlib import cm,colors

output_file("contour.html")
cmap = cm.get_cmap("jet") #choose any matplotlib colormap here
num_slabs = 10 # number of color steps
jet_10 = [colors.rgb2hex(m) for m in cmap(np.arange(0,cmap.N,cmap.N/(num_slabs-1)))]
vmin = 0
vmax = 1550
N = 200
x = np.linspace(0, 10, N)
y = np.linspace(0, 10, N)
xx, yy = np.meshgrid(x, y)
d = vmax * (1. + np.sin(xx)*np.cos(yy))

source = ColumnDataSource(data={'d': [d], 'xx': [x], 'yy': [y]})
p = figure(plot_width=400,plot_height=400,x_range=[0, 10], y_range=[0, 10],min_border_right=10)
p.image(image="d", x=[0], y=[0], dw=[10], dh=[10], palette=jet_10,source=source)

# The following code is for the colorbar:
pcb = figure(plot_width=80,plot_height=400,x_range=[0, 1], y_range=[0, vmax],min_border_right=10)
pcb.image(image=[np.linspace(vmin,vmax,100).reshape(100,1)],x=[0],y=[0],dw=[1],dh=[vmax-vmin], palette=jet_10)
pcb.xaxis.major_label_text_color = None
pcb.xaxis.major_tick_line_color = None
pcb.xaxis.minor_tick_line_color = None
pcb.yaxis[0].ticker=FixedTicker(ticks=np.linspace(vmin,vmax,num_slabs+1)) # 11 ticks
pgrid = gridplot([[p,pcb]])  # this places the colorbar next to the image
show(pgrid)

The output will look like: 如何使用Bokeh(或其他库)在python中制作等高线图?

输出看起来像: