Panel仪表板切换Select控件时Seaborn图表不更新问题
问题描述
我尝试搭建搭载Seaborn可视化图表的Panel仪表板,代码运行后可正常展示控件与初始渲染的图表,但选择不同年份或月份选项时,图表不会触发更新,已尝试.servable()、gridspec等不同实现方式,问题始终存在。
初始测试代码
import xarray as xr import seaborn as sns import panel as pn import matplotlib.pyplot as plt import numpy import pandas as pd pn.extension() x = [numpy.datetime64('2011-01-01T00:00:00.000000000'), numpy.datetime64('2011-01-02T00:00:00.000000000'), numpy.datetime64('2011-01-03T00:00:00.000000000'), numpy.datetime64('2011-01-04T00:00:00.000000000'), numpy.datetime64('2011-01-05T00:00:00.000000000'), numpy.datetime64('2011-01-06T00:00:00.000000000'), numpy.datetime64('2011-01-07T00:00:00.000000000'), numpy.datetime64('2011-01-08T00:00:00.000000000'), numpy.datetime64('2011-01-09T00:00:00.000000000'), numpy.datetime64('2011-01-10T00:00:00.000000000'), numpy.datetime64('2011-01-11T00:00:00.000000000'), numpy.datetime64('2011-01-12T00:00:00.000000000'), numpy.datetime64('2011-01-13T00:00:00.000000000'), numpy.datetime64('2011-01-14T00:00:00.000000000'), numpy.datetime64('2011-01-15T00:00:00.000000000'), numpy.datetime64('2011-01-16T00:00:00.000000000'), numpy.datetime64('2011-01-17T00:00:00.000000000'), numpy.datetime64('2011-01-18T00:00:00.000000000'), numpy.datetime64('2011-01-19T00:00:00.000000000'), numpy.datetime64('2011-01-20T00:00:00.000000000'), numpy.datetime64('2011-01-21T00:00:00.000000000'), numpy.datetime64('2011-01-22T00:00:00.000000000'), numpy.datetime64('2011-01-23T00:00:00.000000000'), numpy.datetime64('2011-01-24T00:00:00.000000000'), numpy.datetime64('2011-01-25T00:00:00.000000000'), numpy.datetime64('2011-01-26T00:00:00.000000000'), numpy.datetime64('2011-01-27T00:00:00.000000000'), numpy.datetime64('2011-01-28T00:00:00.000000000'), numpy.datetime64('2011-01-29T00:00:00.000000000'), numpy.datetime64('2011-01-30T00:00:00.000000000'), numpy.datetime64('2011-01-31T00:00:00.000000000'), numpy.datetime64('2011-02-01T00:00:00.000000000'), numpy.datetime64('2011-02-02T00:00:00.000000000'), numpy.datetime64('2011-02-03T00:00:00.000000000'), numpy.datetime64('2011-02-04T00:00:00.000000000'), numpy.datetime64('2011-02-05T00:00:00.000000000'), numpy.datetime64('2011-02-06T00:00:00.000000000'), numpy.datetime64('2011-02-07T00:00:00.000000000'), numpy.datetime64('2011-02-08T00:00:00.000000000'), numpy.datetime64('2011-02-09T00:00:00.000000000'), numpy.datetime64('2011-02-10T00:00:00.000000000'), numpy.datetime64('2011-02-11T00:00:00.000000000'), numpy.datetime64('2011-02-12T00:00:00.000000000'), numpy.datetime64('2011-02-13T00:00:00.000000000'), numpy.datetime64('2011-02-14T00:00:00.000000000'), numpy.datetime64('2011-02-15T00:00:00.000000000'), numpy.datetime64('2011-02-16T00:00:00.000000000'), numpy.datetime64('2011-02-17T00:00:00.000000000'), numpy.datetime64('2011-02-18T00:00:00.000000000'), numpy.datetime64('2011-02-19T00:00:00.000000000'), numpy.datetime64('2011-02-20T00:00:00.000000000'), numpy.datetime64('2011-02-21T00:00:00.000000000'), numpy.datetime64('2011-02-22T00:00:00.000000000'), numpy.datetime64('2011-02-23T00:00:00.000000000'), numpy.datetime64('2011-02-24T00:00:00.000000000'), numpy.datetime64('2011-02-25T00:00:00.000000000'), numpy.datetime64('2011-02-26T00:00:00.000000000'), numpy.datetime64('2011-02-27T00:00:00.000000000'), numpy.datetime64('2011-02-28T00:00:00.000000000'), numpy.datetime64('2011-03-01T00:00:00.000000000')] y = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 2.0, 0.0, 0.0, 0.0, 1.0, 6.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 1.0, 3.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0] data = pd.DataFrame({'time':x, 'value':y}) month_options = {'Januar' : 1, 'Februar' : 2} month = pn.widgets.Select(name='Monat', options = month_options, value=1) @pn.depends(month) def dashboard(month): subset = data[data.time.dt.month == month] def frosteindringtiefe(ds): sns.set_theme(style="whitegrid") f, ax = plt.subplots(figsize=(15, 6)) bar = sns.barplot(x=ds.time, y=ds.value) ax.set_xticklabels(labels=range(len(ds.time))) plt.title(list(month_options.keys())[month -1 ]) plt.ylabel('Frosteindringtiefe in cm') return bar bar1 = frosteindringtiefe(subset) return bar1 pn.panel(pn.Row(month,dashboard))
问题排查更新
已将代码替换为硬编码的测试数据,问题仍未解决,因此可以排除xarray模块相关的诱因,当前测试直接使用pandas DataFrame作为数据源。已尝试过如下几种启动方式:
- 方式1:
server = pn.panel(pn.Row(month,dashboard)) server.servable()
- 方式2:直接输出server变量
server
- 方式3:直接调用show方法启动
pn.panel(pn.Row(month,dashboard)).show()
上述所有方式均可正常加载初始页面,但切换月份控件选项后图表始终不会刷新更新;如果直接修改月份控件的初始value值(从1改为2),初始加载的图表会正确对应展示2月的数据。
错误原因与修复方案
核心错误有2个:
- 返回值类型不被Panel识别为可更新的渲染对象:渲染函数最终返回的是seaborn的
Axes对象(sns.barplot的返回值),Panel无法正确监听这个对象的重绘需求,只会在首次加载时渲染一次,后续控件值变更时不会触发刷新。 - Matplotlib图表内存泄漏问题:每次触发更新时会新建
plt.subplots()画布,但旧画布没有被关闭,多次切换后会产生大量冗余画布对象,也会干扰渲染逻辑。
修复后的可运行代码
import seaborn as sns import panel as pn import matplotlib.pyplot as plt import numpy import pandas as pd pn.extension() # 测试数据保持不变 x = [numpy.datetime64('2011-01-01T00:00:00.000000000'), numpy.datetime64('2011-01-02T00:00:00.000000000'), numpy.datetime64('2011-01-03T00:00:00.000000000'), numpy.datetime64('2011-01-04T00:00:00.000000000'), numpy.datetime64('2011-01-05T00:00:00.000000000'), numpy.datetime64('2011-01-06T00:00:00.000000000'), numpy.datetime64('2011-01-07T00:00:00.000000000'), numpy.datetime64('2011-01-08T00:00:00.000000000'), numpy.datetime64('2011-01-09T00:00:00.000000000'), numpy.datetime64('2011-01-10T00:00:00.000000000'), numpy.datetime64('2011-01-11T00:00:00.000000000'), numpy.datetime64('2011-01-12T00:00:00.000000000'), numpy.datetime64('2011-01-13T00:00:00.000000000'), numpy.datetime64('2011-01-14T00:00:00.000000000'), numpy.datetime64('2011-01-15T00:00:00.000000000'), numpy.datetime64('2011-01-16T00:00:00.000000000'), numpy.datetime64('2011-01-17T00:00:00.000000000'), numpy.datetime64('2011-01-18T00:00:00.000000000'), numpy.datetime64('2011-01-19T00:00:00.000000000'), numpy.datetime64('2011-01-20T00:00:00.000000000'), numpy.datetime64('2011-01-21T00:00:00.000000000'), numpy.datetime64('2011-01-22T00:00:00.000000000'), numpy.datetime64('2011-01-23T0
相关产品推荐
相关产品推荐

