从脚本(而不是jupyter)使用hvplot绘图时,通常的工作流程是这样的:
import hvplot
hvplot.hvPlot(data)
hvplot.show()调用hvplot.show将导致打开浏览器的新选项卡以呈现绘图。
我希望能够重用相同的浏览器选项卡在相同的图形上重新绘制,以类似于matplotlib hold函数的方式。
我在文档上找不到任何关于它的东西。hvplot支持流式传输,但是在jupyter笔记本之外使用它的开销太大了。
有人知道怎么做吗?
发布于 2019-12-05 04:10:10
更新图形的一种方法是使用参数化的类并使用tornado 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,在我看来,它提供了一个更容易的流接口(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已被弃用。
https://stackoverflow.com/questions/56296063
复制相似问题