Plotly堆叠柱状图周级显示异常,仅日级可正常展示
问题描述
我有如下DataFrame:
Date rank_. category genre breakdown count 0 2022-01-01 top 50 dutch hiphop 7 1 2022-01-01 top 50 dutch pop 12 2 2022-01-01 top 50 other 31 3 2022-01-01 top 50 other dutch 0 4 2022-01-01 top 100 dutch hiphop 2 ... ... ... ... ... 5515 2023-04-05 top 100 other dutch 0 5516 2023-04-05 top 200 dutch hiphop 11 5517 2023-04-05 top 200 dutch pop 16 5518 2023-04-05 top 200 other 74 5519 2023-04-05 top 200 other dutch 1
用Plotly绘制日级日期作为X轴的堆叠百分比柱状图时显示正常,但把Date列改成周格式(比如37-2022这种“周数-年份”格式)后,图表直接为空。我猜测是日期格式和字符串类型的差异导致的,但不知道怎么解决,相关代码如下:
counts = df.groupby(['Date', 'genre breakdown'])['track_isrc'].nunique() # 创建包含统计结果的DataFrame counts_df = counts.reset_index(name='count') # 计算每个日期下,各流派占总数的百分比 counts_df['percent'] = counts_df.groupby('Date')['count'].apply(lambda x: x / x.sum() * 100) # 定义流派的显示顺序 category_order = ['Dutch Pop', 'Dutch HipHop'] # 创建堆叠百分比柱状图 fig = px.bar(counts_df, x='Date', y='percent', color='genre breakdown', barmode='stack', category_orders={"genre breakdown": category_order}, color_discrete_sequence=px.colors.qualitative.Pastel)
问题原因与解决办法
核心原因
改成37-2022这种字符串格式后,Plotly可能仍将其识别为日期时间类型而非普通字符串,但这种格式不符合标准日期解析规则,导致X轴无法正确渲染,最终图表为空。另外还有两个潜在问题:
category_order里的流派名称是大写开头的Dutch Pop、Dutch HipHop,但DataFrame里的流派是小写的dutch pop、dutch hiphop,大小写不匹配会导致对应流派的柱子无法显示。- 数据中存在
count=0的行,可能干扰百分比计算和图表渲染。
解决步骤
1. 强制将Date列视为字符串分类
在处理完周格式转换后,显式将Date列转为字符串,或者通过category_orders指定X轴顺序,让Plotly将其当作分类变量处理:
# 方法1:显式转为字符串 counts_df['Date'] = counts_df['Date'].astype(str) # 方法2:指定X轴的排序,强制按分类渲染 date_order = sorted(counts_df['Date'].unique())
2. 修正流派名称的大小写匹配
把category_order里的名称改成和DataFrame完全一致的小写:
category_order = ['dutch pop', 'dutch hiphop']
3. 过滤无效数据(可选)
提前过滤掉count=0的行,减少无效数据对图表的干扰:
counts_df = counts_df[counts_df['count'] > 0]
完整修正后的代码
# 假设已将原始Date列转换为周格式,例如: # df['Date'] = df['Date'].dt.strftime("%V-%Y") counts = df.groupby(['Date', 'genre breakdown'])['track_isrc'].nunique() counts_df = counts.reset_index(name='count') # 过滤count为0的行 counts_df = counts_df[counts_df['count'] > 0] # 计算百分比 counts_df['percent'] = counts_df.groupby('Date')['count'].apply(lambda x: x / x.sum() * 100) # 修正流派顺序,匹配DataFrame中的名称 category_order = ['dutch pop', 'dutch hiphop'] # 获取排序后的周日期 date_order = sorted(counts_df['Date'].unique()) # 绘图 fig = px.bar(counts_df, x='Date', y='percent', color='genre breakdown', barmode='stack', category_orders={"genre breakdown": category_order, "Date": date_order}, color_discrete_sequence=px.colors.qualitative.Pastel) fig.show()
内容的提问来源于stack exchange,提问作者jsb92
相关产品推荐
相关产品推荐

