一键更新Excel中的图表
场景: 小编每周都要更新最近12周的“生产订单周报”给老板,而且要对比最近两年相同周数的数据。主要是两张图,一张是“一周生产订单对比”,另一张是“各部门订单比例”。虽然在Excel表中建了数据透视表,但是每周都还是需要花时间进行一通凶猛的操作,才能搞定。可不可以每周一键更新,并得到这两张图呢?
代码实现:
import pandas as pd
file = '生产订单.xlsx'
df = pd.read_excel(file)
df.fillna(0, inplace=True)
df["数量"] = df["数量"].astype('int')
# 增加周数字段
df["周数"] = df["日期"].dt.week
df["年份"] = df["日期"].dt.year
# print(df.head())
# 获取当前周数
import datetime
year, current_week, day = datetime.datetime.now().isocalendar()
# print(current_week)
# 只获取最近12周的数据
df_required = df[(df["周数"] >= (current_week - 36)) & (df["周数"] <= (current_week - 24))]
# print(df_required['年份'])
result = df_required.groupby(["周数", "年份"])['数量'].sum().reset_index() # reset后才是DF,不然是Series
# print(result)
#
# # print(result[result["年份"]==2019]["数量"])
#
# 如果有中文,需要配置中文字体,不然会显示成方框
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
# 数据和标签
qty_2019 = result[result["年份"] == 2019]["数量"]
qty_2020 = result[result["年份"] == 2020]["数量"]
print(qty_2020)
x_label = result[result["年份"] == 2019]["周数"]
# 设置字体大小
mpl.rcParams['font.size'] = 12
# 设置图片大小
plt.figure(figsize=(12, 6))
# 设置柱形图宽度
bar_width = 0.45
index = np.arange(13)
qty_2019_list = [qty for qty in qty_2019]
qty_2020_list = [qty for qty in qty_2020]
print(f"index: {len(index)}")
print(len(qty_2019_list))
print(len(qty_2020_list))
# 绘制2019年数据
qty1 = plt.bar(index, qty_2019, bar_width, color='#336633', label="2019")
# 绘制2020年数据
qty2 = plt.bar(index + bar_width, qty_2020, bar_width, color='#6666CC', label="2020")
# X,Y轴标题
plt.xticks(index + bar_width, x_label)
plt.xlabel("周数", fontsize=14)
plt.ylabel("产品数量/台", fontsize=14)
# 图表标题
plt.title(u'每周生产订单对比', fontsize=20)
# 图例显示
plt.legend()
# 添加数据标签
def add_labels(qtys):
for qty in qtys:
height = qty.get_height()
plt.text(qty.get_x() + qty.get_width() / 2, height, height, ha='center', va='bottom')
# 柱形图边缘用白色填充
qty.set_edgecolor('white')
add_labels(qty1)
add_labels(qty2)
plt.savefig('prod_order.png')
# 按部门计算订单数量
order_2019 = df_required[df_required["年份"] == 2019]
# print(order_2019)
dept_2019 = order_2019["部门"].value_counts()
# print(dept_2019)
order_2020 = df_required[df_required["年份"] == 2020]
# print(order_2020)
dept_2020 = order_2020["部门"].value_counts()
# print(dept_2020)
# 绘制饼图
import matplotlib as mpl
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
mpl.rcParams['font.size'] = 12
fig = plt.figure(figsize=(12, 6))
axl = fig.add_subplot(1, 2, 1)
def my_label(pct, allvals):
absolute = int(pct / 100. * np.sum(allvals))
return "{:.1f}%\n({:d})".format(pct, absolute)
explode = (0.1, 0, 0, 0, 0)
plt.pie(dept_2019, autopct=lambda x: my_label(x, dept_2019), explode=explode, labels=dept_2019.index, shadow=True,
startangle=150)
plt.title("各部门订单比例\n(最近12周)_2019", fontsize=20)
# plt.label("2019",fontsize = 14)
ax2 = fig.add_subplot(1, 2, 2)
plt.pie(dept_2020, autopct=lambda x: my_label(x, dept_2020), explode=explode, labels=dept_2020.index, shadow=True,
startangle=150)
plt.title("各部门订单比例\n(最近12周)_2020", fontsize=20)
plt.savefig('order_byDept.png')