繁体   English   中英

HoloViews/Panel - 类型错误:* 不支持的操作数类型:“函数”和“点”

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM