首页 > 解决方案 > 散景散点图:是否可以覆盖按类别着色的线?

问题描述

我有一个数据框,详细说明了各种产品类别的销售与时间的关系。我想为每个类别制作一个销售与时间的“线和标记”图。令我惊讶的是,这在 Bokeh 中似乎非常困难。

散点图很简单。但是随后尝试使用相同的源覆盖销售线与日期(这样我可以在源更新时一次性更新散点图和线图),并且线的颜色与颜色相匹配散点图标记被证明几乎是不可能的。

具有人为数据的最小可重复示例:

import pandas as pd

df = pd.DataFrame({'Date':['2020-01-01','2020-01-02','2020-01-01','2020-01-02'],\
                'Product Category':['shoes','shoes','grocery','grocery'],\
              'Sales':[100,180,21,22],'Colors':['red','red','green','green']})

df['Date'] = pd.to_datetime(df['Date'])

from bokeh.io import output_notebook
output_notebook()
from bokeh.io import output_file, show
from bokeh.plotting import figure


source = ColumnDataSource(df)
plot = figure(x_axis_type="datetime", plot_width=800, toolbar_location=None)

plot.scatter(x="Date",y="Sales",size=15, source=source, fill_color="Colors", fill_alpha=0.5, \
         line_color="Colors",legend="Product Category")

for cat in list(set(source.data['Product Category'])):  
    tmp = source.to_df()
    col = tmp[tmp['Product Category']==cat]['Colors'].values[0]                                                                                                          
    plot.line(x="Date",y="Sales",source=source, line_color=col)   

show(plot)

这是它的样子,这显然是错误的:

这是我想要但不知道如何制作的东西:

Bokeh 不能制作这样的图,其中散点标记和线条在每个类别中具有相同的颜色,并带有图例吗?

标签: pythonbokeh

解决方案


解决方案是将数据分组。然后,您可以为每个组绘制线条。

最小的例子

import pandas as pd
from bokeh.plotting import figure, show, output_notebook
output_notebook()

df = pd.DataFrame({'Date':['2020-01-01','2020-01-02','2020-01-01','2020-01-02'],
                   'Product Category':['shoes','shoes','grocery','grocery'],
                   'Sales':[100,180,21,22],'Colors':['red','red','green','green']})
df['Date'] = pd.to_datetime(df['Date'])

plot = figure(x_axis_type="datetime", 
              plot_width=400, 
              plot_height=400, 
              toolbar_location=None
             )
plot.scatter(x="Date",
             y="Sales",
             size=15, 
             source=df, 
             fill_color="Colors", 
             fill_alpha=0.5,
             line_color="Colors",
             legend_field="Product Category"
            )

for color in df['Colors'].unique():  
    plot.line(x="Date", y="Sales", source=df[df['Colors']==color], line_color=color)     

show(plot)

输出

用每组线绘制


推荐阅读