散景:如何在图例中添加图例和非固定颜色边界?

问题描述 投票:0回答:1

我有一个要使用bokeh的bokeh.plotting.figure.Figure.image绘制的二维数组。效果很好。

现在,我想使用图像所用的颜色添加图例。我没有发现任何案例。我要实现的图例类似于图片。

example plot

from bokeh.models import LinearColorMapper, ColorBar
from bokeh.plotting import figure, show

plot = figure(x_range=(0,1), y_range=(0,1), toolbar_location="right")
color_mapper =  LinearColorMapper(palette="YlGn9", low=-1, high=1, nan_color="white")
plot.image(image=[ndvi], color_mapper=color_mapper,dh=[1.0], dw=[1.0], x=[0], y=[0])

color_bar = ColorBar(color_mapper=color_mapper,label_standoff=12, border_line_color=None, location=(0,0))

plot.add_layout(color_bar, 'right')

此外,我希望有一些自定义的颜色边界,且间隔不固定。这是一个使用matplotlib的示例:

cmap = colors.ListedColormap(['#27821f', '#3fa336', '#6ce362','#ffffff','#e063a8' ,'#cc3b8b','#9e008c','#59044f'])
bounds = [-1000, -500, -100, 0, 50, 100, 300, 500, 10000000]
norm = colors.BoundaryNorm(bounds, cmap.N)
fig, ax = plt.subplots()
ax.imshow(data, cmap=cmap, norm=norm)
python bokeh
1个回答
1
投票

您可以选择红黄绿色调色板。在bokeh中,名称为“ RdYlGn5”,其中末尾的数字表示需要多少种颜色。要在图例中使用它,您需要从RdYlGn5导入bokeh.palettes

为了创建图例,我只知道使用一些伪字形,如下面的代码所示。

我更新了示例,增加了以非固定间隔设置自定义范围的新要求。 This post提供了一些指导。基本上,该想法是使用具有重复颜色的较大颜色表。这种格式不适用于一般类型的边界,但至少在最低和最高边界被解释为无穷大时,它才适合您。

我还尝试用一些自定义空间来布置图例,以使所有标签对齐。选择背景颜色与图例条目形成对比。

有一个颜色条,用于验证颜色图边界在内部如何工作。验证后,您可以将其省略。示例图像的值介于-1000到1000之间,以显示如何处理超出严格的颜色图限制的值。

这里是带有伪数据的示例:

from bokeh.models import LinearColorMapper, Legend, LegendItem, ColorBar, SingleIntervalTicker
from bokeh.plotting import figure, show
import numpy as np

x, y = np.meshgrid(np.linspace(0, 10, 1000), np.linspace(0, 10, 1000))
z = 1000*np.sin(x + np.cos(y))

plot = figure(x_range=(0, 1), y_range=(0, 1), toolbar_location="right")
base_colors = ['#27821f', '#3fa336', '#6ce362','#ffffff','#e063a8' ,'#cc3b8b','#9e008c','#59044f']
bounds = [-1000, -500, -100, 0, 50, 100, 300, 500, 10000000]
low = -600
high = 600
bound_colors = []
j = 0
for i in range(low, high, 50):
    if i >= bounds[j+1]:
        j += 1
    bound_colors.append(base_colors[j])
color_mapper = LinearColorMapper(palette=bound_colors, low=low, high=high, nan_color="white")

plot.image(image=[z], color_mapper=color_mapper, dh=[1.0], dw=[1.0], x=[0], y=[0])

# these are a dummy glyphs to help draw the legend
dummy_for_legend = [plot.line(x=[1, 1], y=[1, 1], line_width=15, color=c, name='dummy_for_legend')
                    for c in base_colors]
legend_labels = [f'     < {bounds[1]}'] + \
                [('' if l < 0 else '     ' if l < 10 else '   ' if l < 100 else ' ')
                 + f'{l} ‒ {h}' for l, h in zip(bounds[1:], bounds[2:-1])] + \
                [f'     > {bounds[-2]}']

legend1 = Legend(title="NDVI", background_fill_color='gold',
                 items=[LegendItem(label=lab, renderers=[gly]) for lab, gly in zip(legend_labels, dummy_for_legend) ])
plot.add_layout(legend1)

color_bar = ColorBar(color_mapper=color_mapper, label_standoff=12, border_line_color=None, location=(0, 0),
                     ticker=SingleIntervalTicker(interval=50))
plot.add_layout(color_bar)

show(plot)

example plot

© www.soinside.com 2019 - 2024. All rights reserved.