Python动态图见得多了?Excel:亦可赛艇!我可是身经百战了

2020-10-26 16:57:55 浏览数 (1)

作者: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

0 人点赞