如何在Python Plotly图表右侧添加终点值分布曲线?
解决方案:时间序列模拟路径图+终点值分布折线图
需求说明
我正在用Python绘制时间序列数据的模拟路径图,希望可视化终点值的分布。现有模拟路径图中,我需要提取时间=T的终点值,在图表右侧添加一条仅展示折线(非箱型图)的分布图以呈现分布偏度,同时保留各时间点的hover数据。我使用Plotly绘图,数据为通用模拟路径,当前代码如下:
import plotly.express as px import plotly.graph_objects as go from plotly.graph_objs.scatter.marker import Line fig = go.Figure(go.Scatter( x=y_testing.index, y=y_testing.iloc[:, 0] )) for i in range(1, len(y_testing.columns)-1): fig.add_trace(go.Scatter( x=y_testing.index, y=y_testing.iloc[:, i] )) fig.show()
其中:
y_testing.index为时间周期y_testing.iloc[:, 0]为实际数据y_testing.iloc[:, i]为各对应模拟路径
修改后代码
import plotly.graph_objects as go from plotly.subplots import make_subplots from scipy.stats import gaussian_kde import numpy as np # 1. 提取终点值(所有模拟路径的最后一个时间点数值) end_values = y_testing.iloc[-1, 1:] # 排除第一列的实际数据 # 2. 创建左右子图,共享Y轴,右侧子图宽度设为更窄 fig = make_subplots( rows=1, cols=2, column_widths=[0.75, 0.25], # 左侧占75%宽度,右侧25% shared_yaxes=True, horizontal_spacing=0.02 # 减小子图间距 ) # 3. 添加实际数据路径到左侧子图 fig.add_trace( go.Scatter( x=y_testing.index, y=y_testing.iloc[:, 0], name="实际数据", line=dict(color="black", width=2), # 突出实际数据 hovertemplate="时间: %{x}<br>数值: %{y}<extra></extra>" ), row=1, col=1 ) # 4. 添加所有模拟路径到左侧子图 for i in range(1, len(y_testing.columns)): fig.add_trace( go.Scatter( x=y_testing.index, y=y_testing.iloc[:, i], name=f"模拟路径{i}", line=dict(color="lightblue", width=0.8), hovertemplate="时间: %{x}<br>数值: %{y}<extra></extra>", showlegend=False # 模拟路径太多,关闭图例避免拥挤 ), row=1, col=1 ) # 5. 计算终点值的核密度估计,生成分布折线 kde = gaussian_kde(end_values) y_vals = np.linspace(end_values.min(), end_values.max(), 200) x_vals = kde(y_vals) # 6. 添加分布折线到右侧子图 fig.add_trace( go.Scatter( x=x_vals, y=y_vals, name="终点值分布", line=dict(color="darkorange", width=2), hovertemplate="数值: %{y}<br>密度: %{x:.4f}<extra></extra>", fill="tozerox", # 可选:填充曲线下方区域增强视觉效果,不需要可删除 showlegend=False ), row=1, col=2 ) # 7. 调整图表布局和样式 fig.update_layout( title="时间序列模拟路径与终点值分布", height=600, width=1000, xaxis_title="时间", yaxis_title="数值" ) # 隐藏右侧子图的X轴刻度标签(只保留折线),调整样式 fig.update_xaxes( visible=False, row=1, col=2 ) fig.update_yaxes( title_text="", row=1, col=2 ) fig.show()
关键细节说明
- 终点值提取:通过
y_testing.iloc[-1, 1:]获取所有模拟路径的最后一个时间点数据,排除第一列的实际数据。 - 子图布局:用
make_subplots创建左右布局,共享Y轴保证分布和路径的数值对应,调整列宽度让路径图成为视觉焦点。 - hover保留:每个
Scattertrace都设置了hovertemplate,确保鼠标悬停时能显示对应时间/数值信息。 - 分布折线生成:使用
scipy.stats.gaussian_kde计算核密度估计,生成平滑的分布折线,能直观展示偏度;如果不需要填充区域,删除fill="tozerox"即可。 - 样式优化:实际数据用黑色粗线突出,模拟路径用浅蓝色细线避免干扰,右侧子图隐藏X轴刻度,只保留分布折线。
内容的提问来源于stack exchange,提问作者finman69
相关产品推荐
相关产品推荐

