使用Pandas与Plotly绘制堆叠面积图未达预期效果的问题求助
解决Plotly堆叠面积图未正确堆叠及异常降0的问题
我明白你遇到的问题了——理论上col1和col2各有100的load,堆叠后最大值应该到200,但px.area画出来的图既没堆叠,还在某些点莫名降到0,单独看每个Label却正常。这其实是因为你的数据格式和Plotly的堆叠逻辑不匹配导致的,咱们一步步解决:
问题根源
Plotly Express的px.area在做堆叠时,要求每个x(time)值必须对应所有y系列(Label)的有效数据。你的数据里存在两个关键问题:
- 时间点不对齐:比如time=16.0只有col1有数据,col2没有;time=30.0只有col2有数据,col1没有。Plotly不会自动为缺失的系列填充0,而是直接跳过该点的堆叠计算,导致堆叠断裂。
- 重复的时间记录:col2有两行time=0.0的记录,这会干扰Plotly对该时间点值的判断,引发异常。
解决方案:数据预处理+正确绘制
咱们先把数据整理成Plotly能正确识别的格式,再绘制堆叠面积图:
步骤1:清理并重塑数据
import pandas as pd import plotly.express as px # 你的原始数据 data = [ [0, "Group", "col1", 0.0, 0.0], [1, "Group", "col1", 15.0, 0.0], [2, "Group", "col1", 16.0, 100.0], [3, "Group", "col1", 106.0, 100.0], [4, "Group", "col1", 116.0, 0.0], [5, "Group", "col2", 0.0, 0.0], [6, "Group", "col2", 0.0, 0.0], [7, "Group", "col2", 30.0, 100.0], [8, "Group", "col2", 90.0, 100.0], [9, "Group", "col2", 100.0, 0.0] ] df = pd.DataFrame(data, columns=["", "Group", "Label", "time", "load"]) df = df.drop(columns=[""]) # 移除多余的索引列 # 1. 去重:删除同一Label+time的重复记录 df = df.drop_duplicates(subset=["Label", "time"], keep="last") # 2. 转成宽格式:每个time点都包含所有Label的load值,缺失的填充0 pivot_df = df.pivot_table( index="time", columns="Label", values="load", fill_value=0 ).reset_index()
步骤2:绘制正确的堆叠面积图
现在用处理后的宽格式数据画图,Plotly就能正确堆叠了:
fig = px.area(pivot_df, x="time", y=["col1", "col2"]) fig.update_layout(title="正确堆叠的面积图", yaxis_title="Total Load") fig.show()
如果你想要更灵活的控制,也可以用Plotly Graph Objects手动添加堆叠层:
import plotly.graph_objects as go fig = go.Figure() # 添加col1的面积层 fig.add_trace(go.Scatter( x=pivot_df["time"], y=pivot_df["col1"], fill='tozeroy', name='col1' )) # 添加col2的面积层,设置fill='tonexty'实现堆叠 fig.add_trace(go.Scatter( x=pivot_df["time"], y=pivot_df["col2"], fill='tonexty', name='col2' )) fig.update_layout(title="手动堆叠的面积图", yaxis_title="Total Load") fig.show()
效果验证
处理后,你会看到在time=30到90之间,col1和col2的load都是100,堆叠后总load达到200;所有时间点的堆叠都能正常衔接,不会出现莫名降0的情况。
内容的提问来源于stack exchange,提问作者stiggy008
相关产品推荐
相关产品推荐

