Plotly Express柱状图X轴因缺失数据乱序,如何保持DataFrame排序顺序?
问题:Plotly柱状图X轴不遵循DataFrame排序后的时序顺序
我有一组年-季度格式的日期数据,对DataFrame执行sort_values排序后顺序正常,但使用Plotly Express绘制柱状图时,X轴会自动将存在缺失类别数据的日期项移至末尾,打乱了原本的时序(比如示例中的2022-Q1被移到最后)。示例代码如下:
# Example data that is not yet ordered on 'Date' import pandas as pd import plotly.express as px df = pd.DataFrame([ ['2021-Q4', 'A', 1], ['2021-Q4', 'B', 5], ['2022-Q1', 'B', 5], ['2023-Q2', 'B', 3], ['2023-Q3', 'B', 16], ['2022-Q2', 'B', 4], ['2022-Q2', 'A', 1], ['2022-Q3', 'B', 5], ['2022-Q4', 'B', 6], ['2022-Q4', 'A', 4], ['2023-Q1', 'A', 1], ['2023-Q1', 'B', 9], ['2023-Q3', 'A', 1] ], columns=['Date', 'Type', 'Count']) # we explicity order the data # Note that now the 2022-Q1 is in between 2021-Q4 and 2022-Q2 df = df.sort_values('Date', key=lambda e: e.replace('Q','')) # Now the x-axis and the broken chronology, i.e., 2022-Q1 at the end fg = px.bar(df, x="Date", y="Count", color="Type", barmode="group") fg.show()
解决方法一:将Date列转为有序分类类型
Plotly会默认对字符串类型的X轴标签按字典序排序,或因部分日期缺少某类数据调整顺序。要强制遵循DataFrame的排序结果,只需把Date列转为有序分类,并指定分类顺序为排序后的唯一日期序列:
import pandas as pd import plotly.express as px df = pd.DataFrame([ ['2021-Q4', 'A', 1], ['2021-Q4', 'B', 5], ['2022-Q1', 'B', 5], ['2023-Q2', 'B', 3], ['2023-Q3', 'B', 16], ['2022-Q2', 'B', 4], ['2022-Q2', 'A', 1], ['2022-Q3', 'B', 5], ['2022-Q4', 'B', 6], ['2022-Q4', 'A', 4], ['2023-Q1', 'A', 1], ['2023-Q1', 'B', 9], ['2023-Q3', 'A', 1] ], columns=['Date', 'Type', 'Count']) # 按规则排序DataFrame df = df.sort_values('Date', key=lambda e: e.replace('Q','')) # 将Date列转为有序分类,指定顺序为排序后的唯一日期值 sorted_dates = df['Date'].unique() df['Date'] = pd.Categorical(df['Date'], categories=sorted_dates, ordered=True) # 绘制柱状图,X轴将严格遵循分类顺序 fg = px.bar(df, x="Date", y="Count", color="Type", barmode="group") fg.show()
解决方法二:绘图时指定category_orders参数
如果不想修改DataFrame的列类型,可直接在调用px.bar时通过category_orders参数强制指定X轴的顺序:
import pandas as pd import plotly.express as px df = pd.DataFrame([ ['2021-Q4', 'A', 1], ['2021-Q4', 'B', 5], ['2022-Q1', 'B', 5], ['2023-Q2', 'B', 3], ['2023-Q3', 'B', 16], ['2022-Q2', 'B', 4], ['2022-Q2', 'A', 1], ['2022-Q3', 'B', 5], ['2022-Q4', 'B', 6], ['2022-Q4', 'A', 4], ['2023-Q1', 'A', 1], ['2023-Q1', 'B', 9], ['2023-Q3', 'A', 1] ], columns=['Date', 'Type', 'Count']) # 排序后获取有序的日期列表 sorted_dates = df.sort_values('Date', key=lambda e: e.replace('Q',''))['Date'].unique() # 绘图时指定X轴的顺序 fg = px.bar(df, x="Date", y="Count", color="Type", barmode="group", category_orders={"Date": list(sorted_dates)}) fg.show()
两种方法都能让X轴严格遵循你指定的时序顺序,不会再出现日期被移至末尾的问题。
内容的提问来源于stack exchange,提问作者Mitchell van Zuylen
相关产品推荐
相关产品推荐

