如何用Plotly绘制以日期为X轴的A、B、other堆叠柱状图?
用Plotly绘制Pandas DataFrame的堆叠柱状图
问题背景
给定如下结构的Pandas DataFrame:
import pandas as pd data={'A': {'2020_01': 3, '2020_02': 3, '2020_03': 1, '2020_04': 3, '2020_05': 1}, 'B': {'2020_01': 0, '2020_02': 0, '2020_03': 3, '2020_04': 0, '2020_05': 2}, 'other': {'2020_01': 0, '2020_02': 0, '2020_03': 3, '2020_04': 0, '2020_05': 2}, 'total': {'2020_01': 3, '2020_02': 3, '2020_03': 7, '2020_04': 3, '2020_05': 5}} df = pd.DataFrame(data)
需要绘制以日期(DataFrame索引)为X轴,A、B、other三列为堆叠数值的柱状图,目前仅能绘制单柱图,代码如下:
import plotly.express as px fig = px.bar(df, x=df.index, y='A', text_auto=True, labels={'A':'bananas'}, height=400) fig.show()
解决方案
方法1:Plotly Express(推荐)
Plotly Express需要长格式数据才能识别多列堆叠,先用pd.melt()转换数据格式,再设置barmode='stack'即可。
完整代码:
import pandas as pd import plotly.express as px # 原始数据初始化 data={'A': {'2020_01': 3, '2020_02': 3, '2020_03': 1, '2020_04': 3, '2020_05': 1}, 'B': {'2020_01': 0, '2020_02': 0, '2020_03': 3, '2020_04': 0, '2020_05': 2}, 'other': {'2020_01': 0, '2020_02': 0, '2020_03': 3, '2020_04': 0, '2020_05': 2}, 'total': {'2020_01': 3, '2020_02': 3, '2020_03': 7, '2020_04': 3, '2020_05': 5}} df = pd.DataFrame(data) # 将宽格式转换为长格式,仅保留需要堆叠的列 df_long = df.melt( value_vars=['A', 'B', 'other'], var_name='类别', value_name='数值', ignore_index=False ).reset_index().rename(columns={'index': '日期'}) # 绘制堆叠柱状图 fig = px.bar( df_long, x='日期', y='数值', color='类别', text_auto=True, labels={'数值': '数量'}, height=400 ) fig.update_layout(barmode='stack') # 开启堆叠模式 fig.show()
方法2:Plotly Graph Objects
无需转换数据格式,逐列添加柱状图并设置base参数实现堆叠:
import pandas as pd import plotly.graph_objects as go # 原始数据初始化 data={'A': {'2020_01': 3, '2020_02': 3, '2020_03': 1, '2020_04': 3, '2020_05': 1}, 'B': {'2020_01': 0, '2020_02': 0, '2020_03': 3, '2020_04': 0, '2020_05': 2}, 'other': {'2020_01': 0, '2020_02': 0, '2020_03': 3, '2020_04': 0, '2020_05': 2}, 'total': {'2020_01': 3, '2020_02': 3, '2020_03': 7, '2020_04': 3, '2020_05': 5}} df = pd.DataFrame(data) fig = go.Figure() # 添加A列作为底层 fig.add_trace(go.Bar( x=df.index, y=df['A'], name='A', text=df['A'], textposition='auto' )) # 添加B列,以A列为基准堆叠 fig.add_trace(go.Bar( x=df.index, y=df['B'], name='B', text=df['B'], textposition='auto', base=df['A'] )) # 添加other列,以A+B列为基准堆叠 fig.add_trace(go.Bar( x=df.index, y=df['other'], name='other', text=df['other'], textposition='auto', base=df['A'] + df['B'] )) # 设置布局 fig.update_layout( barmode='stack', height=400, yaxis_title='数量' ) fig.show()
关键提示
- Plotly Express仅支持长格式数据实现堆叠,宽格式无法直接识别多列,这是之前无法实现的核心原因。
barmode='stack'是堆叠效果的必要设置,两种方法都需要开启。text_auto=True会自动显示每个堆叠块的数值,和你之前的单柱图设置保持一致。
内容的提问来源于stack exchange,提问作者JFerro
相关产品推荐
相关产品推荐

