Holoviews:如何自定义链接时间序列曲线图的直方图

2024-06-28 20:33:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我刚刚开始HoloView。我的问题是关于自定义直方图,但我也分享了一个完整的例子,因为它可能有助于其他新手查看,因为Holoviews的文档非常全面,但可能会非常多

我在文本文件中加载了许多时间序列作为数据帧,其中:

每个文件都针对特定的位置 在每个地点收集了大约10个时间序列,每个时间序列大约有15000个点 我正在构建一个小的交互式工具,其中可以使用一个选择器来选择位置/数据帧,然后使用另一个选择器从10个时间序列中选择3个一起绘制

我的目标是允许链接缩放(x和y比例)。问题和代码将集中在工具的这一方面。 不幸的是,我不能分享我正在使用的实际数据,因为它是专有的,但我创建了3个随机游动,具有与实际数据一致的特定数据范围

## preliminaries ##

import pandas as pd
import numpy as np
import holoviews as hv
from holoviews.util.transform import dim
from holoviews.selection import link_selections
from holoviews import opts
from holoviews.operation.datashader import shade, rasterize
import hvplot.pandas
hv.extension('bokeh', width=100)

## create random walks (one location) ##
data_df = pd.DataFrame()
npoints=15000
np.random.seed(71)
x = np.arange(npoints)
y1 = 1300+2.5*np.random.randn(npoints).cumsum()
y2 = 1500+2*np.random.randn(npoints).cumsum()
y3 = 3+np.random.randn(npoints).cumsum()
data_df.loc[:,'x'] = x
data_df.loc[:,'rand1'] = y1
data_df.loc[:,'rand2'] = y2
data_df.loc[:,'rand3'] = y3

第一块图仅用于绘制数据,并通过设计说明其中一个随机游动与其他两个随机游动的范围不同:

data_df.hvplot(x='x',y=['rand1','rand2','rand3'],value_label='y',width=800,height=400)

hvplot

因此,尽管hvplot子地块可以开箱即用(用于链接),但范围不同,因此缩放比例不太合适:

data_df.hvplot(x='x',y=['rand1','rand2','rand3'], 
               value_label='y',subplots=True,width=800,height=200).cols(1)

subplots

因此,我的第一次尝试是改编文档中Linked brushing的基于Python的点示例:

colors = hv.Cycle('Category10').values
dims   = ['rand1', 'rand2', 'rand3']
layout = hv.Layout([
    hv.Points(data_df, dim).opts(color=c)
    for c, dim in zip(colors, [['x', d] for d in dims])
])
link_selections(layout).opts(opts.Points(width=1200, height=300)).cols(1)

Points

这已经是一个惊人的结果,20分钟的努力

然而,我真正想要的是绘制一条曲线而不是点,并且还可以看到一个直方图,因此我调整了理解语法来处理曲线(在阅读了文档页面Applying customizationComposing elements):

colors = hv.Cycle('Category10').values
dims   = ['rand1', 'rand2', 'rand3']
layout = hv.Layout([hv.Curve(data_df,'x',dim).opts(height=300,width=1200, 
                                                     color=c).hist(dim) for c, 
                    dim in zip(colors,[d for d in dims])])
link_selections(layout).cols(1)

lines

这几乎正是我想要的。但是我仍然在为opts语法的不同层次而挣扎。 问题1:根据上一个代码块的理解,如何使直方图与曲线共享颜色?

现在,假设我想rasterize绘制图(尽管我认为在这种情况下,15000个点还不是很必要),我尝试用Points修改第一个示例:

cmaps = ['Blues', 'Greens', 'Reds']
dims   = ['rand1', 'rand2', 'rand3']
layout = hv.Layout([
    shade(rasterize(hv.Points(data_df, dims), 
                    cmap=c)).opts(width=1200, height = 400).hist(dims[1])
    for c, dims in zip(cmaps, [['x', d] for d in dims])
])
link_selections(layout).cols(1)

rasterized 这是一个不错的开始,但我还是很难选择/定制

问题2:在上面的cod块中,我将如何传递颜色映射(它不像现在那样工作),以及如何使直方图像前一种情况一样反映数据值(并且具有正确的颜色映射)?

谢谢大家!


Tags: 数据importdffordatanpwidthhv
2条回答

Sander回答了如何给柱状图上色的问题,但对于另一个关于给DataShade绘图上色的问题,Datashader使用颜色贴图而不是单一颜色来呈现数据,因此参数名为cmap,而不是color。因此,在数据阴影的情况下使用cmap是正确的,但是(a)cmap实际上是shade的一个参数(它对rasterize的输出进行颜色映射),并且(b)您实际上不需要shade,因为现在大多数情况下可以让Bokeh进行颜色映射,在这种情况下cmap是一个选项而不是一个参数。例如:

from bokeh.palettes import Blues, Greens, Reds
cmaps = [Blues[256][200:], Greens[256][200:], Reds[256][200:]]
dims   = ['rand1', 'rand2', 'rand3']
layout = hv.Layout([
    rasterize(hv.Points(data_df, ds)).opts(cmap=c,width=1200, height = 400).hist(dims[1])
    for c, ds in zip(cmaps, [['x', d] for d in dims])
])
link_selections(layout).cols(1)

enter image description here

为了回答第一个让直方图与曲线颜色相同的问题,我在代码中添加了.opts(opts.Histogram(color=c))
当您有一个布局时,您可以像这样指定布局内元素的选项

colors = hv.Cycle('Category10').values
dims   = ['rand1', 'rand2', 'rand3']
layout = hv.Layout(
    [hv.Curve(data_df,'x',dim)
         .opts(height=300,width=600, color=c)
         .hist(dim)
         .opts(opts.Histogram(color=c)) 
     for c, dim in zip(colors,[d for d in dims])]
)
link_selections(layout).cols(1)

相关问题 更多 >