首页 > 解决方案 > 在 x 轴上创建带有年份月份的 pandas 数据帧的平面图

问题描述

我有一个数据系列,由各个会计年度的月销售额组成。我正在使用pandas数据框来存储数据。每个会计年度从三月的第一天开始,到次年二月的最后一天结束。我正在使用分plotly面图来显示一年中的月份垂直对齐,因此 2021 年 3 月低于 2020 年 3 月,依此类推。

尽管对 x 轴使用分类变量,但排序略有偏差。我尝试使用具有唯一值的“yearmon”变量进行排序,但这也不起作用。具体来说,在下图中,2018 年 1 月和 2 月的值是空白的,2021 年 1 月和 2 月的值也不合适。我怎样才能在没有这些问题的情况下获得显示连续数据的方面?编辑:我觉得它与类别的顺序有关,但还没有设法确定它。

使用 plotly 和 pandas 数据框的分面图

import pandas as pd
import numpy as np
import plotly.express as px
import chart_studio.plotly as py

rng = np.random.default_rng(12345)
df = pd.DataFrame(rng.integers(80, 100, size=(36, 1)), columns=list('A'))
df.index = pd.date_range("2018-03-01", periods=36, freq="M")
df['year'] = df.index.strftime('%Y')
df['month'] = df.index.strftime('%b')
df['monthindex'] = df.index.strftime('%m')
df['yearmon'] = df['year']+df['monthindex']

month_categories = ['Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec','Jan','Feb']
df["month"] = pd.Categorical(df["month"], categories = month_categories)
df = df.sort_values(by = "yearmon")

fig = px.bar(df, x = 'month', y = 'A', facet_col='year', facet_col_wrap=1)
py.image.save_as(fig, 'plotly.png', width=1000, height=500)

更新

使用下面@vestland 的代码作为基础,我根据下面的评论调整了开始日期和财政年度分配,因为财政年度通常与日历年不一致。此外,数据系列的长度是任意的——可能是几个月,也可能是十年——开始和结束月份也是如此。最后,我希望 x 轴以财政年度的第一个月和最后几个月开始和结束,所以在这种情况下(三月和二月)“三月”应该是左边的第一个刻度线,“二月”右边的最后一个。如果这不够清楚,我深表歉意。

import pandas as pd
import numpy as np
import plotly.express as px
import chart_studio.plotly as py

rng = np.random.default_rng(12345)
df = pd.DataFrame(rng.integers(80, 100, size=(36, 1)), columns=list('A'))
df.index = pd.date_range("2018-01-01", periods=36, freq="M")
df['year'] = df.index.strftime('%Y')
df['month'] = df.index.strftime('%b')
df['monthindex'] = df.index.strftime('%m')
df['yearmon'] = df['year']+df['monthindex']

month_categories = ['Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec','Jan','Feb']
df["month"] = pd.Categorical(df["month"], categories = month_categories)
df = df.sort_values(by = "yearmon")

df['fiscal_year'] = [2017]*2+[2018]*12+[2019]*12+[2020]*10
fig = px.bar(df, x = 'month', y = 'A', facet_col='fiscal_year', facet_col_wrap=1)
fig.show()

这似乎给出了以下信息: 使用非日历会计年度绘图

标签: pythonpandasplotlyplotly-python

解决方案


在这种情况下,问题似乎是 plotly 不尊重用于 x 轴的 pandas 数据系列中类别的顺序,除非特别指示这样做,正如在此处的 plotly 论坛中指出的那样在此处记录。category_orders在调用中使用px.bar允许我们覆盖默认的 plotly 假设并创建一个从指定财政年度的第一个月到财政年度最后一个月的 x 轴。

import pandas as pd
import numpy as np
import plotly.express as px
import chart_studio.plotly as py

rng = np.random.default_rng(12345)
df = pd.DataFrame(rng.integers(80, 100, size=(36, 1)), columns=list('A'))
df.index = pd.date_range("2018-01-01", periods=36, freq="M")
df['year'] = df.index.strftime('%Y')
df['month'] = df.index.strftime('%b')
df['monthindex'] = df.index.strftime('%m')
df['yearmon'] = df['year']+df['monthindex']

month_categories = ['Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec','Jan','Feb']
df["month"] = pd.Categorical(df["month"], categories = month_categories)
df = df.sort_values(by = "yearmon")

df['fiscal_year'] = [2017]*2+[2018]*12+[2019]*12+[2020]*10

fig = px.bar(df, x = 'month', y = 'A', 
              facet_col='fiscal_year',
              facet_col_wrap=1,
              category_orders={ # replaces default order by column name
                "month": ['Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec','Jan','Feb']
            })       
fig.show() 

使用有序类别的 pandas 数据框的多面图


推荐阅读