Plotly Express分组柱状图间隙与排序异常问题求助
Plotly分组柱状图按日期独立排序及格式异常处理
问题背景
现有一个包含Date、Name、Number三列的DataFrame,包含5个日期(数量随数据提取时间变化),每个日期对应10个Name;Name可重复出现或仅出现一次,Number可正可负。数据已按Date(ascending=True)、Number(ascending=False)排序。
尝试用Plotly Express绘制Y轴为Number、X轴为Date、按Name着色的分组柱状图,要求每个日期内的柱条按Number从大到小排序。使用代码fig = px.bar(df, x="Date", y="Number", color="Name", barmode="group")时,仅首个日期排序正确,后续日期存在柱条间隙,且排序错误(如正数柱条出现在负数之后)。尝试fig.update_layout(yaxis={'categoryorder': 'total ascending'})无效。
进一步排查发现,排序规则由X轴首个日期决定:若Name在首个日期存在但后续日期不存在,后续日期会出现空白;若Name不在首个日期但在后续日期存在,其柱条会排在末尾,即便Number更大。需要实现每个X轴值对应的柱条独立排序。
复现代码(2个日期场景)
import pandas as pd import plotly.express as px df = pd.DataFrame({ "Name": ["Joe", "Tom", "Tim", "Alex", "Ben", "Steve", "Nick", "Alan", "Jack", "George", "Joe", "Tom", "Tim", "Leo", "Alex", "Ben", "Nick", "Alan", "Jack", "George"], "Date": (["01-01-2024"] * 10) + (["01-02-2024"] * 10), "Number": [0.5, 0.4, 0.3, 0.2, 0.1, -0.1, -0.2, -0.3, -0.4, -0.5, 0.5, 0.4, 0.3, 0.2, 0.1, -0.1, -0.2, -0.3, -0.4, -0.5] }) df["Date"] = pd.to_datetime(df["Date"]) df.sort_values(by=["Date", "Number"], ascending=[True, False], inplace=True) print(df) fig=px.bar(df, x="Date", y="Number", color="Name", barmode="group") fig.show()
更新:排序解决后出现格式异常
采用r-beginners提供的代码后,排序和间隙问题解决,但出现柱条重叠、大间隙等格式错误。
输入数据
| Date | Name | Number |
|---|---|---|
| 2024-02-19 | B | 80.0 |
| 2024-02-19 | C | 70.0 |
| 2024-02-19 | A | 40.0 |
| 2024-02-19 | D | 30.0 |
| 2024-02-19 | E | 10.0 |
| 2024-02-19 | G | -20.0 |
| 2024-02-19 | F | -40.0 |
| 2024-02-19 | J | -50.0 |
| 2024-02-19 | I | -60.0 |
| 2024-02-19 | H | -90.0 |
| 2024-02-20 | A | 140.0 |
| 2024-02-20 | C | 90.0 |
| 2024-02-20 | B | 80.0 |
| 2024-02-20 | E | 40.0 |
| 2024-02-20 | K | 10.0 |
| 2024-02-20 | F | -10.0 |
| 2024-02-20 | G | -30.0 |
| 2024-02-20 | I | -40.0 |
| 2024-02-20 | H | -90.0 |
| 2024-02-20 | J | -140.0 |
| 2024-02-21 | C | 100.0 |
| 2024-02-21 | B | 90.0 |
| 2024-02-21 | A | 80.0 |
| 2024-02-21 | D | 30.0 |
| 2024-02-21 | E | 20.0 |
| 2024-02-21 | F | -20.0 |
| 2024-02-21 | G | -40.0 |
| 2024-02-21 | H | -100.0 |
| 2024-02-21 | I | -130.0 |
| 2024-02-21 | J | -150.0 |
| 2024-02-22 | A | 30.0 |
| 2024-02-22 | E | 30.0 |
| 2024-02-22 | B | 20.0 |
| 2024-02-22 | C | 10.0 |
| 2024-02-22 | D | 10.0 |
| 2024-02-22 | F | -20.0 |
| 2024-02-22 | G | -50.0 |
| 2024-02-22 | H | -70.0 |
| 2024-02-22 | I | -70.0 |
| 2024-02-22 | J | -110.0 |
| 2024-02-23 | B | 170.0 |
| 2024-02-23 | C | 90.0 |
| 2024-02-23 | E | 50.0 |
| 2024-02-23 | A | 10.0 |
| 2024-02-23 | D | 10.0 |
| 2024-02-23 | F | 50.0 |
| 2024-02-23 | G | -10.0 |
| 2024-02-23 | H | -80.0 |
| 2024-02-23 | I | -80.0 |
| 2024-02-23 | J | -150.0 |
使用的代码
import plotly.graph_objects as go fig = go.Figure() # 补充颜色字典定义,避免代码报错 color_dict = {name: f'hsl({i*36},70%,50%)' for i, name in enumerate(df['Name'].unique())} for d in df['Date'].unique(): dff = df.query('Date == @d') for n in dff['Name'].unique(): dfn = dff.query('Name == @n') fig.add_trace(go.Bar( x=dfn['Date'], y=dfn['Number'], marker=dict(color=color_dict[n]), name=n, width=60*60*1000 ) ) names = set() fig.for_each_trace( lambda trace: trace.update(showlegend=False) if (trace.name in names) else names.add(trace.name)) unique_dates = df["Date"].unique() min_x = unique_dates[0] max_x = unique_dates[:-1] fig.update_layout(xaxis_range=[min_x, max_x]) fig.update_layout(height=500, width=800, barmode='group') fig.show()
异常表现
输出图表存在柱条重叠、大间隙等格式异常。
内容的提问来源于stack exchange,提问作者Joe Smart
相关产品推荐
相关产品推荐

