怎么用numpy读取excel的数据画三维图_数据民工的工具箱:批量制图

我是阿布布的老父亲,技能树有点杂......

历史学研究僧、不知名管理咨询顾问、实用主义代码搬运者、偷懒至上数据民工、美妆市场的色弱钢铁直男、目前在学带娃。

这年头出来混口饭吃,谁还能不跟数据和图表打点交道?

尤其是咱们数据民工,作为全公司地势最低的一群人,各种数据如流水般从四方奔泻而来,简直不舍昼夜。

今天分享一个批量制图技巧,帮数据民工们减轻负担。

26d6db7f3da96ffd168d5a26ad6e7674.png

Photo by Alex on Unsplash

应用场景

同一维度下存在数量较多的数据分组,且需要对所有分组进行固定模式的可视化展现时。

用人来话就是:需要做几十张或者几百张图,这些图的类型是一样的,只不过展现的数据对象有点不同

举个例子:

制定一个规模在一二百人的销售团队的奖金制度时,需要展示出销售人员上一期的奖金实绩,和切换到新的奖金制度后各种销售预测之下的预期奖金进行比较。

这样可以看到是哪几家欢喜哪几家愁,然后进一步检验新制度是否有效激励销售、是否存在影响销售士气的地方。

再举一例:

各种产品线、品牌、产品分类之下,有数量众多的SKU,需要把它们在某个期间内的增长表现展示出来,并且和市场大盘/竞品数字/公司内部标杆进行比较。

这样可以找到问题SKU和问题时间段后,然后进一步再从内部或者外部的各个维度切入做交叉分析,找到更加明确的问题点。

原理

偷懒这件事,有积极的和消极的两种方向。

消极向的上策是成功说服对方这件事其实不用做;中策乃是拖着让大家发现不做也没什么影响;下策就是在截止日前一天晚上通宵做。

我们来看积极向的偷懒方法,把一件事情做成功一次,然后用经济效率的方式让成功的做法多次重复。就像这样:

a6a03b05155424c8cc26657fd1194350.gif

数据用例

今天用的示例数据,是从公开渠道获得的,2000年以来我国分省年度GDP指数(上年=100),这个指数反映的是当年GDP与上一年相比的变动趋势和程度。

我们想要知道,与全国整体的GDP变动相比,各个省份的GDP变动在时间序列上有什么特点?

在我国34个省级行政区中,我们获取了除港澳台之外的31个区划的数据。为了简化示例,这边先采用4个直辖市的指数来演示:

c8c9f88fd70c3dfa102e52b9b4241d74.png

数据准备

我们用python的matplotlib库来实现可视化,matplotlib库可以接受的理想数据类型是numpy.array,所以我们打算先把excel文件里的数据转换成numpy.array格式。

# 导入pandas库,准备从excel里读取数据

import pandas as pd

# 指定文件位置, 读取数据到名为df_raw的DataFrame

file = 'D:/data.xlsx'

df_raw = pd.read_excel(file)

# 把指定列的value存入根据列名命名的numpy.array里

arr_CN = df_raw.loc[:,'全国'].values

arr_BJ = df_raw.loc[:,'北京'].values

arr_TJ = df_raw.loc[:,'天津'].values

arr_SH = df_raw.loc[:,'上海'].values

arr_CQ = df_raw.loc[:,'重庆'].values

# 运行print(type(arr_CN)),看到返回对象的类型是:

先成功一次

我们先来画全国和北京的GDP指数的对比图。

# 导入制图需要的matplotlib.pyplot库

import matplotlib.pyplot as plt

# 设定图片的风格、字体和字体大小

# 这边设定字体是因为matplotlib默认字体不支持中文字符

# 如果使用英语的话,可以忽略字体关键词

plt.style.use('seaborn')

plt.rcParams.update({"font.size":20,

                     "font.sans-serif":"SimHei"})

# 创建折线图的X轴和Y轴刻度名称

# X轴使用源数据里的年份

# Y轴可以使用默认值,也可以根据数据的范围定制

arr_xtick = df_raw.loc[:,'年度'].values

arr_ytick = [100,102,104,106,108,110,112,114,116,118,120]

# 创建构成图表的对象fig和ax

# 写程序的根本不需要找对象,因为可以自己创建~

fig, ax = plt.subplots()

# 画第一条线:全国GDP指数

ax.plot(arr_xtick, arr_CHN,

        label = '全国',

        linestyle = ':',

        marker = 'o',

        linewidth = 1.5)

# 画第二条线:北京GDP指数

ax.plot(arr_xtick, arr_BJ,

        label = '北京',

        marker = 's',

        linewidth = 3.0)

# 指定X轴和Y轴上的刻度名称和字号

# 为了避免X轴刻度名称重复,我们让刻度名称旋转个45度

ax.set_xticks(arr_xtick)

ax.set_yticks(arr_ytick)

plt.xticks(rotation = 45)

ax.tick_params(axis = 'both',

           which = 'major',

           labelsize = 16)

# 给X轴、Y轴和图表整体标注名称,增加图表的可读性

ax.set_xlabel('年度', fontsize = 20)

ax.set_ylabel('增长指数(去年 = 100)', fontsize = 20)

ax.set_title('国内生产总值增长:全国 vs 北京', fontsize = 20)

ax.legend(prop = {'size':16})

# 规定图表的尺寸,前一个数字是宽度,后一个数字是高度

fig.set_size_inches([15, 8])

运行上面的代码,可以获得下面这张图:

71bc47eb267c4243eb092ba42dd8dbc6.png

复制成功方法

我们再来看一下这张图:

a6a03b05155424c8cc26657fd1194350.gif

为了复制成功的做法,我们还需要一对好基友。

一个是蹲着的雪人

这是一个函数,负责接收待处理的数据,按照规定动作,输出图像。

另一个是流水线

我们要做一个Dict对象,把待处理的数据依次喂给函数。

完整的代码是这样的:

# 导入两个需要用到的python库

import matplotlib.pyplot as plt

import pandas as pd

# 指定excel文件的位置, 读取数据到名为df_raw的DataFrame

file = 'D:/data.xlsx'

df_raw = pd.read_excel(file)

# 把指定列的value存入以列名命名的numpy.array里

arr_CN = df_raw.loc[:,'全国'].values

arr_BJ = df_raw.loc[:,'北京'].values

arr_TJ = df_raw.loc[:,'天津'].values

arr_SH = df_raw.loc[:,'上海'].values

arr_CQ = df_raw.loc[:,'重庆'].values

# 这个就是流水线

# dict的key是城市名

# 对应的value是包含GDP指数的numpy.array

arr_dict = {'北京':arr_BJ,

            '天津':arr_TJ,

            '上海':arr_SH,

            '重庆':arr_CQ}

# 设定图片的风格、字体和字体大小

# 这边设定字体是因为matplotlib默认字体无法显示中文字符

# 如果使用英语的话,可以忽略字体关键词

plt.style.use('seaborn')

plt.rcParams.update({"font.size":20,

                     "font.sans-serif":"SimHei"})

# 创建折线图的X轴和Y轴刻度名称

# X轴使用源数据里的年份

# Y轴可以使用默认值,也可以根据数据的范围定制

arr_xtick = df_raw.loc[:,'年度'].values

arr_ytick = [100,102,104,106,108,110,112,114,116,118,120]

# 把之前成功的方法打包成一个函数(雪人)

# 函数接收的参数有三个:

# 城市名,对应的numpy.array,城市名构成的图表标题

def plot_line_duel(city, arr, title):

    # 创建构成图表的对象fig和ax

    fig, ax = plt.subplots()

    # 画第一条线:全国GDP指数

    ax.plot(arr_xtick, arr_CN,

            label = '全国',

            linestyle = ':',

            marker = 'o',

            linewidth = 1.5)

    # 画第二条线:传进来哪个城市就画哪个城市的

    ax.plot(arr_xtick, arr,

            label = city,

            marker = 's',

            linewidth = 3.0)

    # 指定X轴和Y轴上的刻度名称和字号

    # 为了避免X轴刻度名称重复,我们让刻度名称旋转个45度

    ax.set_xticks(arr_xtick)

    ax.set_yticks(arr_ytick)

    plt.xticks(rotation = 45)

    ax.tick_params(axis = 'both',

                   which = 'major',

                   labelsize = 16)

    # 给X轴、Y轴和图表整体标注名称,增加图表的可读性

    ax.set_xlabel('年度', fontsize = 20)

    ax.set_ylabel('增长指数(去年 = 100)', fontsize = 20)

    ax.set_title(title, fontsize = 20)

    ax.legend(prop = {'size':16})

    # 规定图表的尺寸,前一个数字是宽度,后一个数字是高度

    fig.set_size_inches([15,8])

    # 规定函数的输出:把图片保存到本地

    # 保存文件名:就是传入给到程序的图表标题title

    file_path = 'D:/plotting/'

    file_name = title + '.jpg'

    fig.savefig(file_path + file_name, quality = 100)

# 启动流水线:遍历arr_dict里的每一组key:value

# 把城市名、array、图表标题传给雪人

for key, value in arr_dict.items():

    title = '国内生产总值增长:全国 vs ' + key

    plot_line_duel(key, value, title)

运行完上面这段代码,四个直辖市的GDP指数和全国GDP指数的对比图就静静地躺在目标文件夹里面了:

b7791b6964aa90a3ce7e08b73eced84e.png

接下来我们顺手看看这四张对比图告诉我们的信息:

71bc47eb267c4243eb092ba42dd8dbc6.png d2e868c7c8484a4e8eecf2adc26f7ec6.png

北京和上海有着类似的模式:以2005年为界,之前的增长速度高于全国增长,之后便趋近于全国水平。

32a9caceb3f3aa13aa88a4e2eeab694e.png 992e1e6bf31f1fa534a3f2acdbf61b8c.png

天津和重庆则是另外的模式:与北京和上海不同,2007年之后的十年间这两个直辖市的GDP增长高于全国增长,但是在最近两三年里先后出现回落。

写在最后

本文用四个直辖市的示例数据,介绍了批量生成时间序列上对比折线图的方法。运用中需要注意以下两点:

由于示例数据仅选取了四组,所以这边采用的是比较粗暴的数据获取方式。当需要制图的数据组数较多,比如说我们需要全部31个行政区与全国水平的对比图时,手动创建numpy.array的方式就比较不效率。此时需要再创建一个函数来从源文件里自动读取数据到各自的numpy.array里。

示例演示的图表类型是折线图。其实根据不同分析目的和数据特征,可以采用的还有如柱状图(类别对比)、直方图与箱线图(分布对比)、散点图(相关关系)等。这些图表都可以利用matplotlib生成,各位可以百度一下示例代码,或者参考matplotlib的官方文档。后续我也会在其他的话题里面分享。

谢谢你读到这里

辛苦了

请作者吃个冰淇淋

↓ ↓ ↓

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值