使用Holoviews绘制多条线

6

我有一个长这样的df:

data = {'Cumulative': {0: 4, 1: 18, 2: 24, 3: 24, 4: 4, 5: 20, 6: 32, 7: 42},  'Id': {0: 1, 1: 1, 2: 1, 3: 1, 4: 2, 5: 2, 6: 2, 7: 2},  'Order': {0: '1-1',   1: '1-2',   2: '1-3',   3: '1-4',   4: '1-1',   5: '1-2',   6: '1-3',   7: '1-4'},  'Period': {0: 1, 1: 2, 2: 3, 3: 4, 4: 1, 5: 2, 6: 3, 7: 4},  'Time': {0: '1-1',   1: '1-2',   2: '1-3',   3: '1-4',   4: '1-1',   5: '1-2',   6: '1-3',   7: '1-4'},  'Year': {0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1, 6: 1, 7: 1}}

df = pd.DataFrame(data)

生成的数据框如下所示:

example dataframe

我想使用Holoviews为每个id绘制一条线。因此,'Order'在x轴上,'Cumulative'在y轴上,每个'Id'都有自己的线(所有线颜色相同)。目前为止,我已经做了这个,但结果不正确。
%opts Curve [width=600 height=400 show_grid=True ] (color='indianred', alpha=0.5, line_width=1)

kdims=['Order' ] vdims = ['Cumulative',
            ] ds = hv.Dataset(df.sort_values(by=['Year','Period']), kdims=kdims, vdims= vdims)

ds.to(hv.Curve, ['Order'] ,'Cumulative' )
2个回答

4

HoloViews只知道已声明的维度。这意味着当您执行时,它不知道'Id'列,并且无法对其进行分组。以下是我的建议:

%%opts Curve [width=600 height=400 show_grid=True ] (color='indianred', alpha=0.5, line_width=1)
ds = hv.Dataset(df).sort(['Year', 'Period'])
ds.to(hv.Curve, 'Order' ,'Cumulative', 'Id')

在不声明任何明确的kdim或vdims的情况下,我们声明了数据集。这意味着我们可以使用HoloViews对数据进行排序,然后使用.to方法绘制按'Id'列分组的'Order' vs 'Cumulative'列的曲线。如果您想在一个图上查看所有曲线,只需将其改为ds.to(hv.Curve,'Order','Cumulative','Id').overlay()
生成的图像如下所示,并带有滑块以在不同的'Id'值之间切换: image generated by the code

谢谢!那个方法可行,但我立刻遇到了第二个问题。只能绘制大约130条线,然后就会出现JavaScript错误添加输出!TypeError:无法读取未定义的属性“映射”。请查看您的浏览器JavaScript控制台以获取更多详细信息。 - bowlby
感谢提供 .overlay() 技巧。使用 hv.plot.line 显示所有线条在同一图形中时,这个技巧对摆脱选择器小部件很有用。虽然在 hvplot.line 的文档中似乎没有记录,但确实起作用了。 - user15420598

0

另一种方法是使用覆盖层从曲线列表构建图像。下面的代码将对数据框进行子选择。第一列将用作X轴值,第二列将用作y轴值。

df.loc[df['Id']==1][['Period', 'Cumulative']]

然后创建一个需要绘制的曲线列表。这些曲线不必全部都是曲线,您可以根据需要混合和匹配。

# Specified individually  
list_of_curves = [
    hv.Curve(df.loc[df['Id']==1][['Period', 'Cumulative']], label='Id = 1'), 
    hv.Curve(df.loc[df['Id']==2][['Period', 'Cumulative']], label='Id = 2'), 
]

# As a list comprehension
list_of_curves = [hv.Curve(
    df.loc[df['Id']==the_id][['Period', 'Cumulative']], 
    label=f"Id = {the_id}"
) for the_id in [1,2]]

然后将这个曲线列表传递给一个叠加层,并设置它的选项。

hv.Overlay(list_of_curves).opts(
    height=300, 
    width=600,
    xlabel='Period', 
    ylabel='Cumulative', 
    title='Change in cumulative over period',
    legend_position='right'
)

这将产生以下图形:

figure created by code


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接