【问题标题】:Stacked bar plot disconnected堆积条形图断开连接
【发布时间】:2020-10-16 04:53:29
【问题描述】:

数据来自本网站。 https://www.kaggle.com/kemical/kickstarter-projects

我的堆积条形图已断开连接。我不知道发生了什么。我的数据都不包含任何空值。该系列的值是频率。有没有人遇到过这个?我只是想让我的酒吧连接起来。

fig, ax = plt.subplots(nrows=1, figsize=(15,5))
x = clean_df['main_category'].value_counts().index


print("Number of unique main categories:", clean_df['main_category'].nunique())


for year in [2010, 2011, 2012, 2013, 2014, 2015, 2016]:    
    y = clean_df[clean_df['launched'].dt.year == year]['main_category'].value_counts()
    if year > 2010:
        bottom = clean_df[clean_df['launched'].dt.year <= year-1]['main_category'].value_counts()
    else:
        bottom = 0
        
    ax.set_xlabel("Main Catagories", fontsize=14)
    ax.set_ylabel("Frequency/Count", fontsize=14)
    ax.bar(x=x, height=y, width=0.9, bottom=bottom, label=str(year))
    ax.yaxis.grid(linestyle='-', linewidth=0.7)
    ax.set_xticklabels(x, rotation=45, ha='right')
    ax.legend(loc='upper right')
plt.tight_layout();

【问题讨论】:

  • 每个标签在情节中都有相同的年份(2016)
  • 为什么不用pandas来做堆积条形图呢?似乎会容易得多。
  • 问题可能是clean_df[...]['main_category'].value_counts()在每次调用中改变了类别的顺序(顺序似乎是从大到小值计数,每年不同)。因此,标签与条形不对应。如果您设置 alpha=0.4 左右,您还会看到条形重叠。按照 BigBen 的建议,使用 pandas 或 seaborn 来创建情节会更好。

标签: python pandas matplotlib bar-chart


【解决方案1】:

主要问题是clean_df[...]['main_category'].value_counts() 给出了从大到小排序的值。这可能每年都不同。

[x] 附加到y 可以解决问题,因此可以使用所需的索引有效地对y 进行排序。

要计算条形的底部,在循环结束时累积高度更容易。初始化bottom = 0 和一些pandas 魔法确保bottom += y 求和所需的值。仅当year 没有某个类别的值时,才会为该类别设置na。因此,在yx 重新排序之后使用fillna(0) 可以防止累积na

一个简化的例子:

import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

N = 100
clean_df = pd.DataFrame({'main_category': np.random.choice(list('abcdef'), N),
                         'year': np.random.randint(2010, 2017, N)})
x = clean_df['main_category'].value_counts().index

fig, ax = plt.subplots(nrows=1, figsize=(15, 5))
bottom = 0
for year in [2010, 2011, 2012, 2013, 2014, 2015, 2016]:
    y = clean_df[clean_df['year'] == year]['main_category'].value_counts()[x].fillna(0)
    ax.set_xlabel("Main Catagories", fontsize=14)
    ax.set_ylabel("Frequency/Count", fontsize=14)
    ax.bar(x=x, height=y, width=0.9, bottom=bottom, label=str(year), alpha=0.8)
    ax.yaxis.grid(linestyle='-', linewidth=0.7)
    ax.set_xticklabels(x, rotation=45, ha='right')
    ax.legend(loc='upper right')
    bottom += y
plt.tight_layout()
plt.show()

PS:用 pandas 创建这个情节:

df_plot = clean_df.groupby(['year', 'main_category']).size().reset_index().pivot(columns='year', index='main_category', values=0)
df_plot['total'] = df_plot.sum(axis=1)
df_plot.sort_values('total', ascending=False, inplace=True)
df_plot[df_plot.columns[:-1]].plot(kind='bar', stacked=True, rot=45)

请注意,您可能需要在 clean_df 中创建一个仅包含年份的新列。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-26
    • 2014-02-09
    • 2020-02-05
    • 2020-09-14
    • 1970-01-01
    • 2016-10-13
    • 2017-10-14
    相关资源
    最近更新 更多