如何为多站点时序数据实现基于数值的着色可视化?
当然可以实现基于参数数值的差异化着色!针对你的多站点时序数据(带突变特征)的可视化需求,我整理了几个可行方案,同时解决你用散点图时时间轴的问题,还有针对性的优化建议:
方案1:使用Plotly实现动态时序着色(推荐)
Plotly对时序数据和颜色映射的支持非常友好,不仅能轻松实现基于数值的着色,还支持交互式操作(放大、悬停查看数值),很适合观察突变点。
import numpy as np import pandas as pd import string import plotly.graph_objects as go from plotly.subplots import make_subplots # 生成模拟数据(和你原代码一致) cols = string.ascii_uppercase[:5] # 取前5个站点方便演示 ndays = 3 index = pd.date_range('2018-05-01', periods=3*24*60, freq='T') d1 = np.random.randn(len(index)//ndays, len(cols)) d2 = np.random.randn(len(index)//ndays, len(cols))+2 d3 = np.random.randn(len(index)//ndays, len(cols))-2 data = np.concatenate([d1, d2, d3]) df = pd.DataFrame(data=data, index=index, columns=list(cols)) # 创建子图,每个站点一个子图(可选,也可以画在同一图) fig = make_subplots(rows=len(cols), cols=1, shared_xaxes=True, vertical_spacing=0.02) # 为每个站点添加着色的折线图 cmap = 'RdYlBu_r' # 选择合适的颜色映射 for i, col in enumerate(cols): fig.add_trace( go.Scatter( x=df.index, y=df[col], mode='lines', line=dict(width=1), marker=dict(color=df[col], colorscale=cmap, showscale=(i==0)), # 只显示一次颜色条 name=col ), row=i+1, col=1 ) fig.update_layout(height=800, title_text="多站点时序数据数值着色可视化") fig.update_yaxes(title_text="参数值") fig.show()
这个方案的优势:
- 完全支持datetime类型的x轴,无需额外转换
- 悬停时可以直接查看时间、站点和对应数值,方便定位突变点
- 颜色条自动关联数值范围,直观展示数值高低
方案2:Matplotlib实现静态折线分段着色
如果你更倾向于使用Matplotlib,可以把每个站点的时序数据拆分成连续的线段,根据每个点的数值映射颜色,再逐个绘制:
import numpy as np import pandas as pd import string import matplotlib.pyplot as plt from matplotlib import cm from matplotlib.colors import Normalize # 生成模拟数据(同上) cols = string.ascii_uppercase[:5] ndays = 3 index = pd.date_range('2018-05-01', periods=3*24*60, freq='T') d1 = np.random.randn(len(index)//ndays, len(cols)) d2 = np.random.randn(len(index)//ndays, len(cols))+2 d3 = np.random.randn(len(index)//ndays, len(cols))-2 data = np.concatenate([d1, d2, d3]) df = pd.DataFrame(data=data, index=index, columns=list(cols)) # 设置颜色映射和归一化 cmap = cm.RdYlBu_r norm = Normalize(vmin=df.values.min(), vmax=df.values.max()) # 创建画布 fig, axes = plt.subplots(nrows=len(cols), ncols=1, figsize=(12, 8), sharex=True) # 为每个站点绘制分段着色的折线 for ax, col in zip(axes, cols): x = df.index y = df[col] # 遍历每个连续点对,绘制线段并着色 for i in range(len(x)-1): ax.plot(x[i:i+2], y[i:i+2], color=cmap(norm(y[i])), linewidth=1) ax.set_ylabel(col) ax.grid(alpha=0.3) # 添加颜色条 sm = cm.ScalarMappable(norm=norm, cmap=cmap) sm.set_array([]) fig.colorbar(sm, ax=axes, orientation='horizontal', pad=0.05) plt.xlabel("时间") plt.tight_layout() plt.show()
解决你之前散点图的问题:如果坚持用散点图,只需把datetime索引转成matplotlib能识别的数值(x=df.index.to_pydatetime()或者x=df.index.astype('int64')//1e9),不过折线图更适合时序数据的趋势展示。
时序数据突变可视化优化建议
- 添加颜色条: 不管用哪种工具,都要加上颜色条,让数值和颜色的对应关系清晰可见
- 突出突变区间: 可以在突变发生的时间点添加垂直参考线(比如
ax.axvline(pd.Timestamp('2018-05-02'), color='k', linestyle='--')),快速定位突变位置 - 使用交互式工具: Plotly或Bokeh的交互式功能,能让你自由放大突变区域,查看细节
- 合并相似站点: 如果站点数量太多,可以先对站点聚类,把相似趋势的站点放在同一子图,避免视觉混乱
- 标注突变极值: 对突变点的极值添加文本标注,直接展示关键数值
内容的提问来源于stack exchange,提问作者AjanO
相关产品推荐
相关产品推荐

