首先,我要补充HoloViews的开发人员,这件事非常棒。有很多部分,有点难以弄清楚如何把它们放在一起做我想做的事情:)。
我正在尝试进行链接的多维数据绘图,即我希望有几个图表显示各个维度的相同数据的视图。然后,我希望利用Bokeh选择工具在其中一个图中选择数据,并查看它在其他图中的位置。但是我还需要使用Datashader来做这件事,因为我的数据集很大。
这是我到目前为止(在Jupyter笔记本中运行,使用python 2)
import numpy as np
import pandas as pd
import holoviews as hv
import holoviews.operation.datashader as hvds
hv.notebook_extension('bokeh')
%opts Scatter [tools=['box_select', 'lasso_select']] (size=10 nonselection_color='red' color='blue') Layout [shared_axes=True shared_datasource=True]
# Create some data to plot
x1 = np.arange(0,10,1e-2)
x2 = np.arange(0,10,1e-2)
X1,X2 = np.meshgrid(x1,x2)
x1 = X1.flatten()
x2 = X2.flatten()
x3 = np.sin(x1) * np.cos(x2)
x4 = x1**2 + x2**2
# Pandas dataframe object from the data
print "Creating Pandas dataframe object"
df = pd.DataFrame.from_dict({"x1": x1, "x2": x2, "x3": x3, "x4": x4})
# Put the dataframe into a HoloViews table
dtab = hv.Table(df)
# Make some linked scatter plots using datashader
scat1 = dtab.to.scatter('x1', 'x2', [])
scat2 = dtab.to.scatter('x1', 'x3', [])
scat3 = dtab.to.scatter('x2', 'x4', [])
hvds.datashade(scat1) + hvds.datashade(scat2) + hvds.datashade(scat3)
这会产生以下内容
非常简单。然而,它并没有完全符合我的要求。数据范围和平移的变化是相关联的,这是非常酷的,但是在一个绘图范围之外的数据仍然可以绘制在其他绘图上。我希望所有图中的数据都消失,这样我才能看到所有查看数据范围内的数据,这样人们就可以动态选择一些超立方体数据在多维空间中突出显示。
此外,让Bokeh选择工具以相同的方式工作会很好,例如我可以在一个图上选择一些点,并将它们全部显示为红色或其他图形。尽管如此,我仍然没有得到选择工具,尽管他们要求选择' box_select'和' lasso_select'。我可能错误地要求他们,但我并不清楚HoloViews如何传递选项。
答案 0 :(得分:4)
您可以使用HoloViews Streams选择仅使用当前可见点显示的数据。有一个例子:https://anaconda.org/petrenko/linking_datashaders
答案 1 :(得分:4)
根据詹姆斯的回答(https://stackoverflow.com/a/44288019/1447953),我将问题中的例子扩展到以下内容。它将一个图作为“主”控制源,并且仅将该图的数据范围内出现的数据绘制到一堆“从”图上。拥有双向关系会很好,但这很酷。
import numpy as np
import pandas as pd
import holoviews as hv
import holoviews.operation.datashader as hvds
hv.notebook_extension('bokeh')
%opts Layout [shared_axes=False shared_datasource=True]
# Create some data to plot
x1 = np.arange(0,10,1e-2)
x2 = np.arange(0,10,1e-2)
X1,X2 = np.meshgrid(x1,x2)
x1 = X1.flatten()
x2 = X2.flatten()
x3 = np.sin(x1) * np.cos(x2)
x4 = x1**2 + x2**2
# Pandas dataframe object from the data
print "Creating Pandas dataframe object"
df = pd.DataFrame.from_dict({"x1": x1, "x2": x2, "x3": x3, "x4": x4})
# Make some linked scatter plots using datashader
x1_x2 = hv.Points(df[['x1', 'x2']])
#x1_x3 = hv.Points(df[['x1', 'x3']])
#x2_x4 = hv.Points(df[['x2', 'x4']])
from holoviews import streams
maindata=x1_x2
mainx='x1'
mainy='x2'
def create_dynamic_map(xvar,yvar):
def link_function(x_range, y_range):
x_min = x_range[0]; x_max = x_range[1]
y_min = y_range[0]; y_max = y_range[1]
pts = hv.Points(df[ (getattr(df,mainx) > x_min) & (getattr(df,mainx) < x_max)
& (getattr(df,mainy) > y_min) & (getattr(df,mainy) < y_max)
][[xvar, yvar]])
return pts
dmap = hv.DynamicMap(link_function,
streams=[hv.streams.RangeXY(x_range=(-100,100),
y_range=(-100,100),
source=maindata)],
kdims=[])
return dmap
x1_x3 = create_dynamic_map('x1','x3')
x2_x4 = create_dynamic_map('x2','x4')
hvds.datashade(x1_x2) + hvds.datashade(x1_x3) + hvds.datashade(x2_x4)