首页 > 解决方案 > 散景图例对象 - 将分配的颜色传递给图例

问题描述

我正在尝试创建一个相当复杂的散景圆图,其中包含几个复杂的交互(轴变化和年份滑块等)。我似乎已经让它大部分工作了,并且没有使用 ColumnDataSource (因为我借来的模板没有使用它)。现在我需要创建一个自定义图例(或 HoverTool(??))。

我设法创建了一个自定义图例,但我不知道如何将它分配给图例的 matplotlib 颜色传递。所以目前,它只是一个显示所有图例项目但没有颜色标识符的图例。如何将正确的颜色传递给图例?

这是我的代码的相关块:

数据框:

FULLNAME | ES | TX | YEAR
Jim        3    12   2008
...
Tim        33    8   2009


import matplotlib
import random
from datetime import date

user_list= list(set((df["FULLNAME"])))

colordict=dict(matplotlib.colors.cnames.items())
colordict=list(colordict.values())
random_colors=random.sample(colordict,len(user_list))

def yr_slider():
    current=slider.value
    ys=df[y.value][df["YEAR"]==current].values
    p = figure(plot_width=930, plot_height=325, background_fill_color='snow', x_range=(2016,2019))
    p.circle(x=df["YEAR"][df["YEAR"]==current], y=ys, size= 20,
             color=random_colors)
    legend=Legend(items=[("Jim",random_colors[1]),
                         ("Tim",[])
                         ]) ###THIS AINT WORKIN RIGHT###
    p.add_layout(legend,'right')
    print(ys)
    return p

def update(attr, old, new):
    layout2.children[1]=yr_slider()
slider=Slider(start=2017, end=date.today().year, step=1, value=date.today().year, title="Year")
slider.on_change('value', update)

y=Select(title='X-Axis', value='ES',options=['TX','ES'])
y.on_change('value',update)

ctrls=widgetbox([y,slider], width=200)
layout2=row(ctrls,yr_slider())

curdoc().add_root(layout2)

谢谢!

标签: python-3.xpandasmatplotlibcolorsbokeh

解决方案


图例项将标签与渲染器列表相关联,而不是与颜色相关联。

legend = Legend(items=[(label,list_of_GlyphRenderers)])

当列表中有多个 Glyphrenderer 时,如果它们属于同一类型,则只会显示第一个的颜色。

如果第一个使用多种颜色,则只显示第一种颜色。

如果 Glyphrenderer 是不同的类型(例如圆形和线),那么它们将组合在图例的小图标中。

您可以将多个渲染器附加到同一个图例项这一事实对此非常有用,并且可以在启用交互式图例时同时控制多个渲染器的可见性。

这里只有一个渲染器circle(),但颜色不同,所以只会使用第一种颜色。我不知道直接自定义图例图标的方法。

您可以为每个点单独调用 Circle

from bokeh.io import show
from bokeh.models import Legend
from bokeh.plotting import figure

names = ["Jim","Bob","Assia"]
colors = ["red","blue","green"]

fig = figure()
items = []
for i in range(3):
    items += [(names[i],[fig.circle(i,i,color=colors[i],size=20)])]
fig.add_layout(Legend(items=items),'right')
show(fig)

但是如果你有很多点,使用 Hovertool 可能会更好。


推荐阅读