[英]HoloViews/Panel - TypeError: unsupported operand type(s) for *: 'function' and 'Points'
我正在尝试在holoviews.operation.datashader.spread
操作上创建参数px
,该参数可以交互更改,并带有一个额外的覆盖层。
pn.bind(get_spreaded, px=px_slider) is working as expected when executing with
。
但是有一个额外的覆盖,行pn.Column(px_slider, interactive * other)
报告TypeError: unsupported operand type(s) for *: 'function' and 'Points'
。
如何将*
运算符与从pn.bind(...)
返回的 function 一起使用?
或者这是错误的方法吗? 有更好更简单的解决方案吗?
我在 jupyter 实验室中运行了以下代码:
import holoviews as hv
import panel as pn
import numpy as np
from holoviews.operation.datashader import rasterize, spread
import colorcet
import pandas as pd
hv.extension('bokeh')
pn.extension()
hv.opts.defaults(
hv.opts.Path(width=800, height=400),
hv.opts.Image(width=800, height=400)
)
def random_walk(n, f=200):
"""Random walk in a 2D space, smoothed with a filter of length f"""
xs = np.convolve(np.random.normal(0, 0.1, size=n), np.ones(f)/f).cumsum()
ys = np.convolve(np.random.normal(0, 0.1, size=n), np.ones(f)/f).cumsum()
xs += 0.1*np.sin(0.1*np.array(range(n-1+f))) # add wobble on x axis
xs += np.random.normal(0, 0.005, size=n-1+f) # add measurement noise
ys += np.random.normal(0, 0.005, size=n-1+f)
return np.column_stack([xs, ys])
# create a path and plot it
path = hv.Path([random_walk(10000, 30)])
path
# rasterize and show the plot
rasterized = rasterize(path).opts(colorbar=True, cmap=colorcet.fire, cnorm='log')
rasterized
# the callback for getting the spreaded plot
def get_spreaded(px=3, shape='circle'):
return spread(rasterized, px=px, shape=shape)
# show the plot returned from the callback
get_spreaded()
# create the slider for interactively changing the px value
px_slider = pn.widgets.IntSlider(name='Number of pixels to spread on all sides', start=0, end=10, value=3, step=1)
# bind the slider to the callback method
interactive = pn.bind(get_spreaded, px=px_slider)
# show only one plot without any overlay
pn.Column(px_slider, interactive)
# create data for an overlay
df = pd.DataFrame(data={'c1': [1, 2, 3, 4, 5], 'c2': [3, 4, 5, 6, 7]})
other = hv.Points(data=df)
other
# show both plots
pn.Column(px_slider, interactive * other)
最后一行导致以下错误消息:
#
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[159], line 1
----> 1 pn.Column(px_slider, interactive * other)
TypeError: unsupported operand type(s) for *: 'function' and 'Points'
我希望有某种方法可以包装 function 并可以使用*
运算符。 但我还没有找到办法。
虽然在这种特殊情况下,function 的返回值是 HoloViews 可以(原则上)与其他 plot 重叠的东西,但 HoloViews 不知道; HoloViews *
运算符只知道如何处理 HoloViews 对象(Elements、HoloMaps、Layouts 和 DynamicMaps),而不是绑定的 Panel 函数。
您可以像使用pn.bind
一样使用 DynamicMap,但此处 HoloViews 操作已经了解如何处理 Panel 小部件,因此您可以简单地将小部件提供给spread
操作(或任何其他操作的参数):
import panel as pn, numpy as np, holoviews as hv, colorcet, pandas as pd
from holoviews.operation.datashader import rasterize, spread
hv.extension('bokeh')
pn.extension()
hv.opts.defaults(
hv.opts.Path(width=800, height=400),
hv.opts.Image(width=800, height=400)
)
def random_walk(n, f=200):
"""Random walk in a 2D space, smoothed with a filter of length f"""
xs = np.convolve(np.random.normal(0, 0.1, size=n), np.ones(f)/f).cumsum()
ys = np.convolve(np.random.normal(0, 0.1, size=n), np.ones(f)/f).cumsum()
xs += 0.1*np.sin(0.1*np.array(range(n-1+f))) # add wobble on x axis
xs += np.random.normal(0, 0.005, size=n-1+f) # add measurement noise
ys += np.random.normal(0, 0.005, size=n-1+f)
return np.column_stack([xs, ys])
# create plot with interactively controlled spreading
px_slider = pn.widgets.IntSlider(name='Number of pixels to spread on all sides',
start=0, end=10, value=3, step=1)
path = hv.Path([random_walk(10000, 30)])
rasterized = rasterize(path).opts(colorbar=True, cmap=colorcet.fire, cnorm='log')
spreaded= spread(rasterized, px=px_slider, shape='circle')
# create data for an overlay
df = pd.DataFrame(data={'c1': [1, 2, 3, 4, 5], 'c2': [3, 4, 5, 6, 7]})
other = hv.Points(data=df)
# show both plots
pn.Column(px_slider, spreaded * other)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.