在脚本中使用hvplot进行绘图(不在jupyter上)时,通常的工作流程如下:
import hvplot
hvplot.hvPlot(data)
hvplot.show()
调用hvplot.show
将导致打开浏览器新选项卡以渲染图。
我希望能够重用相同的浏览器选项卡以在同一图形上重新绘制,其方式类似于使用matplotlib hold
函数所能实现的功能。
我在文档上找不到任何相关内容。 hvplot支持流传输,但是在jupyter笔记本之外使用它会产生太多开销。
有人知道该怎么做吗?
答案 0 :(得分:0)
更新图形的一种方法是使用参数化的类并使用龙卷风PeriodicCallback
,有关详细信息,请参见param,panel - param和tornado.ioloop的文档。
from hvplot import hvPlot
import numpy as np
import pandas as pd
import param
import panel as pn
import tornado
class Plot(param.Parameterized):
df = param.DataFrame(precedence=-1)
def __init__(self, **params):
super(Plot, self).__init__(**params)
self.generate_df() # create a first random dataframe
self.set_plot() # create a first plot with our new dataframe
# Once the bokeh server (for serving our plot to a webpage) is started,
# the underlying tornado server is taking control.
# To be able to fetch (or here: generate) new data, we have to register
# our method with the tornado ioloop.
# To poll for new data, the PeriodicCallback can be used.
self.cb = tornado.ioloop.PeriodicCallback(self.generate_df, 1000, .2)
self.cb.start() # start the callback
# self.callback.stop () ## In this example not implemented, callback runs indefinitely
def generate_df(self):
print('generate df')
self.df = pd.DataFrame(np.random.randint(90,100,size=(5, 1)), columns=['1'])
@param.depends('df', watch=True)
def set_plot(self):
self.plot = hvPlot(self.df)
@param.depends('df', watch=True)
def dashboard(self):
return self.plot()
b = Plot(name="Plot")
app = pn.panel(b.dashboard)
server = app.show(threaded=False)
在此示例中,每次更改数据框时都会重绘整个图(例如,每次都会重置缩放...)。 对情节外观的进一步更改将需要其他回调。
如果仅数据更改,则返回到Streams。
在这里,我将从hvplot
切换到holoviews
,在我看来,这为Streams(holoviews - Responding to Events)提供了更简单的界面。
第一种方法更改为
import holoviews as hv
from holoviews.streams import Stream, param
import numpy as np
import pandas as pd
import param
import panel as pn
import tornado
# returns an hv.Overlay of hv.Curves for each column
# in a given data frame
def interactive_df(df):
curve_list = []
for column in df.columns.values:
curve_list.append(hv.Curve(df[column]))
overlay = hv.Overlay(curve_list)
return overlay
class Plot2(param.Parameterized):
df = param.DataFrame(precedence=-1)
DF = Stream.define('DF', df=df) # definition of a stream class, source is df
streamdf = DF() # instance of the stream class 'DF'
# stream data are provided to a dynamic map
dmap = hv.DynamicMap(interactive_df, streams=[streamdf])
def __init__(self, **params):
super(Plot2, self).__init__(**params)
self.generate_df() # create a first random dataframe
self.set_plot() # create a first plot with our new dataframe
self.cb = tornado.ioloop.PeriodicCallback(self.generate_df, 1000, .2)
self.cb.start() # start the callback
# self.callback.stop () ## In this example not implemented, callback runs indefinitely
def generate_df(self):
self.df = pd.DataFrame(np.random.randint(90,100,size=(100, 1)), columns=['1'])
@param.depends('df', watch=True)
def set_plot(self):
self.dmap.event(df=self.df)
s = Plot2(name="Plot Stream")
app = pn.panel(s.dmap)
server = app.show(threaded=False)
由于仅更改数据,可以使用框缩放等,而不会出现任何问题。
此外:matplotlib的文档说,hold
已过时。