Python使用Matpoltlib绘制堆叠柱形图

70 阅读2分钟

引入依赖

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

显示中文和负号

plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['axes.unicode_minus'] = False

数据预处理

df = pd.read_excel('movie_box_office.xlsx')
# print(df.to_string())
# 数据预处理
df_date = ['2023-10-01', '2023-10-02', '2023-10-03', '2023-10-04', '2023-10-05', '2023-10-06', '2023-10-07']
# 获取国庆7天票房排名前三电影的数据
Means = {}
for d in df_date:
    df111 = df[df['日期'] == d].head(3)
    df1111 = df111[['电影名称', '当前票房']]
    df1111['当前票房'] = df1111['当前票房'].div(10000)
    Means[d] = df1111.sort_values('当前票房', ascending=True)
# 计算阶梯差距
Means1 = []
Means2 = []
Means3 = []
Means_sum = []
for i in Means:
    Means1.append(Means[i]['当前票房'].iloc[0])
    Means2.append(Means[i]['当前票房'].iloc[1])
    Means3.append(Means[i]['当前票房'].iloc[2])
    Means_sum.append(Means[i]['当前票房'].iloc[0] + Means[i]['当前票房'].iloc[1] + Means[i]['当前票房'].iloc[2])

Means1 = np.array(Means1)
Means2 = np.array(Means2)
Means3 = np.array(Means3)

绘制堆叠柱形图

# 绘制柱形图
plt.figure(figsize=(12, 6))

p1 = plt.bar(range(len(df_date)), Means1, 0.65)
p2 = plt.bar(range(len(df_date)), Means2, 0.65, bottom=Means1)
p3 = plt.bar(range(len(df_date)), Means3, 0.65, bottom=Means1 + Means2)

plt.ylabel('单位(万元)')
plt.title('2023国庆期间票房前三占比')
plt.xticks(range(len(df_date)), [datetime.strptime(date, '%Y-%m-%d').strftime('%m月%d日') for date in df_date])
plt.yticks(range(0, 300001, 5000))
plt.legend((p1[0], p2[0], p3[0]), ('坚如磐石', '前任4:英年早婚', '志愿军:雄兵出击'))
# 添加文字
for i in range(len(df_date)):
    plt.text(i, Means1[i] / 2, '{:.2%}'.format(Means1[i] / Means_sum[i]), c='w', horizontalalignment='center',
             verticalalignment='center')
    plt.text(i, Means1[i] + Means2[i] / 2, '{:.2%}'.format(Means2[i] / Means_sum[i]), c='w',
             horizontalalignment='center', verticalalignment='center')
    plt.text(i, Means_sum[i] - (Means3[i] / 2), '{:.2%}'.format(Means3[i] / Means_sum[i]), c='w',
             horizontalalignment='center', verticalalignment='center')
    plt.text(i, Means_sum[i] + Means_sum[i] * 0.05, str('{:.2%}'.format(Means_sum[i] / 100)) + '万元',
             horizontalalignment='center', verticalalignment='center')
# 绘制折线图
plt.plot(range(len(df_date)), Means_sum, marker='o', c='r')
# 取消左上边框
plt.gca().spines['top'].set_color('none')
plt.gca().spines['right'].set_color('none')

plt.show()

效果图

Figure_3.png