作者:Ryoko量子
来源:凹凸数据
朋友圈又看到 Python 广告推送了,什么“你还在用 Excel 加班啊”、“我一进去就看见 Python 在打 Excel 啊”…… Py大人,你好大的官威啊!
如今 Python 是个大热门,从基础数据处理,到高端人工智能,都有它的身影。而在数据分析领域,尤其是在可视化部分,Python 的各类绘图库也给用户带来了惊喜,比如各种随时间序列的动态可视化,能够比较清晰地呈现多个指标的变化情况。
可 Excel 就只能画基础图表了吗,难道是我 Excel 拿不动刀了?
今天就来看看,E哥是否能老骥伏枥吧!
效果预览比较
(1)Python版
流畅丝滑,仿佛生命的跃动。
Python版
(2)Excel版
图样图森破,不落下风,对老表哥而言还带有一种亲切感。
Excel版
Excel动态图实现
知识点:offset 函数,开发工具-表单控件,名称管理器,图表数据源关联,VBA 操作单元格。
(1)offset函数
该函数是实现样例动态图的核心要素,让我们看看函数的官方提示,简单来说其 5 个参数就是:OFFSET(起始位置,向下偏移行数,向右偏移列数,向下选取行数,向右选取列数)。
以数据用例来说明,=OFFSET(A1,5,2,3,1)
即表示从 A1 单元格开始,下移 5 格,右移 2 格,再向下选取 3 格,注意:最后的 1 表示选择这一列而不是向右多选一列。
可以在编辑区选中公式按 F9 查看结果,返回了存放该区域值的数组。
据此,可以预想动态图需要用到的数据,就是用 OFFSET 返回的区域作为折线图的系列值。
(2)开发工具-表单控件
但如果想要动态地修改 OFFSET 返回区域,还需要将其偏移、选取相关的参数绑定到单元格,通过修改单元格的值,来修改函数内部参数。故先设置 F2 、G2 两个单元格分别为下移量和下取量,起始位置选择 C1 即可,如此选取日产能值时就无需右移和右取。
要手动输入来修改单元格的值也很麻烦,这时就要来到开发工具菜单栏(若没有这项则需要在 Excel 选项中 call 出来),找到表单控件,本次笔者选用的是滑块。
右键滑块设置控件格式,即可通过滑块来修改单元格的值。
(3)名称管理器
为了便于使用,先在公式菜单栏里找到名称管理器。
添加一个名称为“日产能A厂”,其引用位置为 =OFFSET(Sheet1!C1,Sheet1!F2, ,Sheet1!G2, ),省略的两个参数默认值分别为 0 和 1,如此即可通过滑块调整获得日产能值的区域。
同理添加“SSS能源”和“XX重工”的引用,注意:后面两个的 OFFSET 起始位参数是不一样的,分别是 C501 和 C125 单元格,如此操作的原因可以通过观察原始数据得知。
再添加一个日期段,用作折线图的X轴
(4)图表数据源关联
最后设置图表和数据的关联,先插入一个空的折线图。
右键选择数据,添加Y轴数据。
例如A厂的数据,在系列值处填写之前设置的名称,SSS能源和XX重工同理。
在右侧水平轴标签编辑X轴,填写之前设置的名称。
此时已经可以通过操作滑块来实现动态修改折线图的效果。
如果想以每 7 天为一个周期,查看每个周期的数据,还可以设置起始日滑块的步长为 7,然后修改跨度当前值为 7 。
之后操作起始日滑块效果见下图。
(5)VBA操作单元格
如果想要像效果预览图中那样自动播放该怎么做呢?答案是使用 VBA 。再从表单控件中选择一个按钮,右键该按钮后选择指定宏,点击新建,开始编辑 VBA 代码。
点击按钮运行代码,便可实现 G2 单元格从 1 开始自增,Do While
段的作用是暂停 0.1 秒并执行其他操作(折线图随 G2 值的变动而变动)。
至此,Excel 动态图完成!
Python动态图实现
P版样例图的实现见以下代码,具体可参考笔者的另一篇《程序员的求生欲:用python给女友一个七夕惊喜二维码吧》,其中以动态条形图为例,详细说明了制图思路和完整的实现过程(以及其他加料技巧)。
代码语言:javascript复制import matplotlib.pyplot as plt
import matplotlib.animation as ani
import pandas as pd
import datetime
df = pd.read_excel(r"D:动态折线图数据样例.xlsx") # 读取原始数据
t = datetime.datetime(2020,7,1) # 起始日期
fig = plt.figure(figsize=(10,6)) # 画布
plt.rcParams["font.sans-serif"] = ["Microsoft YaHei"] # 字体设为微软雅黑
timeSlot = list(range(1,63)) [62]*20 # 时间轴
items = ["A厂", "SSS能源", "XX重工"] # 单位列表
colors = ["#6495ED", "#FF8C00", "#B0C4DE"] # 颜色列表
def draw(date):
# 数据处理 ------
date_list = [] # 需绘制的日期段
for d in range(date):
date_list.append(t datetime.timedelta(days=d))
current_date = t datetime.timedelta(days=date) # 最新一天
_df = df[df["日期"]<current_date ] # 获取最新一天前所有数据
# 绘制折线图 ------
fig.clear() # 每次重绘时清空画布
plt.title("0701-0831各单位产能变化", fontsize=20) # 标题
ax = plt.gca() # 坐标轴对象
ax.spines['right'].set_color('none') # 隐藏右边框
ax.spines['top'].set_color('none') # 隐藏上边框
for i,v in enumerate(items):
data = _df[_df["单位"] == v]["日产能"] # 获取某单位某日产能值
plt.plot(date_list, data , color=colors[i]) # 绘制折线
plt.plot(date_list[-1], list(data)[-1], color=colors[i], marker='o', markersize = 10) # 设置最后一个节点样式
plt.text(date_list[-1], list(data)[-1] 1, v, ha='center', va='bottom', fontsize=12) # 为最后一个节点添加数据标签
# draw(62)
animator = ani.FuncAnimation(fig, draw, frames=timeSlot ,interval = 50)
plt.show()
# animator.save('test.gif',fps=20)
结果:
小结
通过本次比较可见,两者均能实现相同的需求。Python 在生成结果的细节调整上会更加便利,并且可以直接输出 Gif 图保存,但图像文件较大;而 Excel 在对原数据进行调整时会更快捷,而且在演示时也可以单步查看,还含有炫技成分(人不装 B枉少年)。
Excel 不仅能做动态图,在日常使用中还是有许多便利之处的。工具是多样的,还是应根据实际情况选择使用。
不知各位是 Excel Exciting!还是 Python 真香!或者是XXX天下第一呢?
数据样例下载
https://alltodata.cowtransfer.com/s/a597fd16484249