2017-05-31 24 views
2

讓我從補充HoloViews開發人員開始,這件事相當了不起。只有很多片斷,想弄清楚如何將它們放在一起做我想做的事情有點困難:)。如何在HoloViews中使用Datashader + Bokeh後端進行鏈接數據選擇

我想在這裏做鏈接的多維數據繪圖,即我想有幾個繪圖顯示沿着各個維度的相同數據的視圖。然後,我想要利用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) 

這將產生以下

enter image description here

這是很簡單的飛馳。但是它並不完全符合我的要求。數據範圍和平移的變化是相互關聯的,這非常酷,但是一個繪圖範圍之外的數據仍然可以繪製在其他繪圖上。我想讓這些數據從所有地塊中消失,這樣我只能看到所有查看數據範圍內的數據,這樣就可以動態地選擇一些超立方體數據以在多維空間中突出顯示。

另外,最好讓Bokeh選擇工具以同樣的方式工作,例如我可以在一個地塊上選擇一些點,並將它們全部顯示爲紅色或其他地塊上的東西。儘管我要求'box_select'和'lasso_select',但我甚至根本沒有選擇工具。儘管我可能會錯誤地詢問它們,但我不清楚HoloViews是如何傳遞選項的。

回答

4

您可以使用HoloViews Streams選擇要使用當前可見點顯示的數據。有一個例子:https://anaconda.org/petrenko/linking_datashaders

+0

哦非常好!關於第二部分的任何想法,即只使用數據選擇而不是繪圖範圍?如果我正確地傳遞工具選項,也許這隻會相當自動地工作。 –

+0

應該有在文檔中的某處使用數據選擇的示例,但如果您沒有看到它們,請在[gitter頻道](https://gitter.im/ioam/holoviews)上提問。 –

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) 
相關問題