plotly-resampler在Jupyter Notebook中缩放时未按预期停止重采样导致X轴数据异常的问题
plotly-resampler在Jupyter Notebook中缩放时未按预期停止重采样导致X轴数据异常的问题
问题描述
我最近在Jupyter Notebook中使用plotly-resampler时遇到了不符合预期的行为,具体情况如下:
- 我准备了5000个毫秒级的时间序列样本,设置了
default_n_shown_samples=1000,并且为每个trace指定了max_n_samples=1000和limit_to_view=True - 按逻辑来说:
- 完全缩小视图时(显示全部5000个点,超过1000),应该触发重采样(图例显示R),这部分表现正常
- 放大到视图内仅显示少量点(远少于1000)时,应该停止重采样(图例不显示R),但实际不管怎么放大,图例始终显示R,说明一直在重采样
- 更严重的是,其中一条值全为0的trace在放大后X轴数据损坏,前两个点挤在一起,明显是重采样算法处理异常导致的
复现代码
from plotly_resampler import FigureWidgetResampler import pandas as pd import numpy as np x = pd.date_range("2023-01-01", periods=5000, freq="ms") y = np.sin(np.linspace(0, 10 * np.pi, 5000)) * 0 + np.arange(5000) z = np.sin(np.linspace(0, 10 * np.pi, 5000)) * 0 fig = FigureWidgetResampler(default_n_shown_samples=1000) fig.add_trace( {"name": "Signal Linear", "x": x, "y": y, "mode": 'lines+markers'}, max_n_samples=1000, limit_to_view=True ) fig.add_trace( {"name": "Signal 0", "x": x, "y": z, "mode": 'lines+markers'}, max_n_samples=1000, limit_to_view=True ) fig.update_layout(showlegend=True) fig.show()
使用版本:
- plotly: 5.24.1
- plotly-resampler: 0.10.0
- 运行环境:Windows + Jupyter Notebook
问题原因分析
- 版本兼容性bug:你使用的
plotly-resampler 0.10.0在处理pandas DatetimeIndex类型的X轴时,可能存在视图内点数计算不准确的问题,导致即使放大后视图内点数远小于1000,仍误判需要重采样。 - 平坦信号的重采样算法缺陷:默认的重采样算法(LTTB,大三角形三通采样)适合处理有波动的信号,但对于像
Signal 0这样全值相同的平坦信号,会出现采样点选择异常,进而导致X轴数据显示错乱。
解决方案
方案1:升级plotly-resampler到最新版本
旧版本的时间序列重采样逻辑存在已知问题,升级到最新稳定版可以修复视图点数计算的bug:
pip install --upgrade plotly-resampler
方案2:为平坦信号更换重采样算法
对于全值相同的平坦信号,避免使用默认的LTTB算法,改用更适合的均匀采样或分箱类算法,在add_trace时通过resampler_kwargs指定:
fig.add_trace( {"name": "Signal 0", "x": x, "y": z, "mode": 'lines+markers'}, max_n_samples=1000, limit_to_view=True, resampler_kwargs={"default_downsampler": "uniform"} # 均匀采样 )
也可以选择"binned_mean"(分箱均值)、"binned_median"等算法,这类算法对平坦信号的处理更稳定。
方案3:将日期X轴转换为数值类型
如果升级版本后问题仍存在,可以将pandas的DatetimeIndex转换为unix时间戳(数值类型),避免日期类型带来的视图计算误差:
# 将日期转换为秒级unix时间戳 x_unix = x.astype(np.int64) // 10**9 fig = FigureWidgetResampler(default_n_shown_samples=1000) fig.add_trace( {"name": "Signal Linear", "x": x_unix, "y": y, "mode": 'lines+markers'}, max_n_samples=1000, limit_to_view=True ) fig.add_trace( {"name": "Signal 0", "x": x_unix, "y": z, "mode": 'lines+markers'}, max_n_samples=1000, limit_to_view=True, resampler_kwargs={"default_downsampler": "uniform"} ) # 将X轴重新格式化为日期显示 fig.update_xaxes(type='date') fig.show()
方案4:切换为FigureResampler替代FigureWidgetResampler
FigureWidgetResampler基于ipywidgets,在某些Jupyter环境下可能存在交互逻辑的异常,尝试使用FigureResampler:
from plotly_resampler import FigureResampler # 替换导入 # 后续代码逻辑基本一致,最后用fig.show()显示 fig = FigureResampler(default_n_shown_samples=1000) # ... 添加trace的代码和之前一致 ... fig.show()
内容来源于stack exchange
相关产品推荐
相关产品推荐

