Python折線圖的分析過程和畫圖的方法

說起折線圖,很多人都覺得非常簡單,不就是一些點連成的線嗎?用 Excel 幾秒鐘就能畫出一張折線圖。

真的就這么簡單嗎?

想一想:在普通的折線圖中,如何自動地添加一條代表平均值的橫線?如何添加一條帶箭頭的趨勢線?如何快速地標(biāo)注最大值和最小值?如何標(biāo)注特殊事件?如何對折線圖進(jìn)行數(shù)據(jù)分析?

下面我們用一個具體的案例,演示折線圖的分析過程和畫圖的方法。

一個案例

根據(jù)某公司 2019 年 9 月份每天的銷量數(shù)據(jù),畫出如下一張折線圖:

通過觀察可以看到,銷量每隔幾天就有一個波谷,對照日歷,發(fā)現(xiàn)一個規(guī)律:這些銷量比較低的日期,都是周末或節(jié)假日。

如果理解了業(yè)務(wù)的周期性,那么在分析數(shù)據(jù)時,就能排除一些干擾,更快地找到對業(yè)務(wù)真正有價值的信息。

排除周期性的因素之后,我們觀察折線圖中的最大值和最小值,看看它們是否在正常范圍以內(nèi),如果不是的話,那么要分析背后的原因。

比如說,9 月 30 日的銷量最高,明顯高于平時的正常水平,經(jīng)過與業(yè)務(wù)溝通和分析發(fā)現(xiàn),是因為這一天做了打折促銷的運營活動。

在折線圖中,有一條代表平均值的橫線,以及一條帶箭頭的趨勢線,它們有助于對數(shù)據(jù)整體趨勢的把握。

從上面的圖中可以看出,中秋節(jié)放假之后,銷量有所上升,結(jié)合廣告費的投入數(shù)據(jù)進(jìn)行分析,計算它們相關(guān)系數(shù),發(fā)現(xiàn)銷量與廣告費之間具有比較強(qiáng)的正相關(guān)性,也就是說,中秋節(jié)之后,銷量上升的主要原因,是公司加大了廣告費的投入。

通過上面的分析解讀,我們知道,折線圖能直觀地反映出數(shù)據(jù)隨著時間變化的趨勢,讓數(shù)據(jù)更容易進(jìn)行對比,發(fā)現(xiàn)數(shù)據(jù)背后規(guī)律性的知識,從而幫助管理者更好地做出決策。

畫圖不是為了炫技,而是為了提高信息傳遞的效率。你不妨反思一下自己畫過的圖,是不是提高了信息傳遞的效率呢?

畫圖方法

能畫折線圖的軟件工具有很多,本文采用的是 Python中的 matplotlib庫。

Jupyter Lab 中運行以下 Python代碼,就可以畫出上面那張折線圖。

讀取數(shù)據(jù)

# 讀取每日銷售數(shù)據(jù)
df = pd.read_excel('2019年9月每日銷售.xlsx')

df
日期  實際銷量
0   2019-09-01  7
1   2019-09-02  16
2   2019-09-03  18
3   2019-09-04  16
4   2019-09-05  18
5   2019-09-06  16
6   2019-09-07  9
7   2019-09-08  7
8   2019-09-09  16
9   2019-09-10  15
10  2019-09-11  17
11  2019-09-12  16
12  2019-09-13  3
13  2019-09-14  6
14  2019-09-15  7
15  2019-09-16  25
16  2019-09-17  23
17  2019-09-18  22
18  2019-09-19  23
19  2019-09-20  21
20  2019-09-21  13
21  2019-09-22  12
22  2019-09-23  22
23  2019-09-24  23
24  2019-09-25  23
25  2019-09-26  22
26  2019-09-27  24
27  2019-09-28  13
28  2019-09-29  12
29  2019-09-30  29

開始分析和畫圖

# 定義畫圖的數(shù)據(jù)
x = df.日期
y = df.實際銷量

# 定義顏色
color1 = '#0085c3'
color2 = '#7ab800'
color3 = '#dc5034'

# 設(shè)置圖像大小
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)

# 繪制折線圖
ax.plot(x, y, marker='o', color=color1)

fig
# 標(biāo)注最大值
ax.text(x[y.idxmax()]+timedelta(hours=-12),
        y.max()+1, y.max(),
        color=color1, fontsize=15)

# 標(biāo)注最小值
ax.text(x[y.idxmin()]+timedelta(hours=-9),
        y.min()-2, y.min(),
        color=color1, fontsize=15)
fig
# 計算 7 天移動平均
y2 = y.rolling(7).mean()

# 繪制趨勢線
ax.plot(x, y2, ls='--', color=color2, label='7 天移動平均')

fig
# 繪制平均值線
ax.hlines(y.mean(), x[0], x[-1:],
          linestyles='-.', colors=color3)

# 標(biāo)注平均值
ax.text(x[-1:]+timedelta(days=-7.5), y.mean()-2,
        '平均值: ' + str(round(y.mean(),1)),
        color=color3, fontsize=15)
fig
# 繪制箭頭
plt.annotate('', xy=(x[-1:], y2[-1:]),
             xytext=(x[-2:-1], y2[-2:-1]),
             arrowprops=dict(arrowstyle='->',
                             color=color2,
                             shrinkB=0))

# 標(biāo)注特殊事件
ax.annotate('中秋節(jié)', xy=(x[y.idxmin()], y.min()), color=color1,
             xytext=(x[y.idxmin()]+timedelta(days=1.5), y.min()-2),
             arrowprops=dict(arrowstyle='->', color=color1), fontsize=15)

ax.annotate('打折促銷', xy=(x[y.idxmax()], y.max()), color=color1,
             xytext=(x[y.idxmax()]+timedelta(days=-5), y.max()+2),
             arrowprops=dict(arrowstyle='->', color=color1), fontsize=15)

fig
# 設(shè)置網(wǎng)格線
ax.grid(ls=':', color='gray', alpha=0.6)

# 設(shè)置圖例的位置和大小
ax.legend(loc='upper left', fontsize=12)

# 設(shè)置坐標(biāo)軸標(biāo)簽的角度和大小
plt.xticks(rotation=90, fontsize=12)
plt.yticks(fontsize=12)

# 設(shè)置 y 軸的刻度范圍
ax.set_ylim(0, y.max()+5)

# 設(shè)置圖表標(biāo)題
_ = ax.set_title('2019年9月每日銷量變化趨勢', fontsize=25)

fig

補充

Series.idxmax(self,axis = 0,skipna = True,* args,** kwargs )返回最大值的行標(biāo)簽

代碼合集

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

# 正常顯示中文標(biāo)簽
plt.rcParams['font.sans-serif'] = ['SimHei']

# 正常顯示負(fù)號
plt.rcParams['axes.unicode_minus'] = False

# 讀取每日銷售數(shù)據(jù)
df = pd.read_excel('./data/2019年9月每日銷售.xlsx')

# 定義畫圖的數(shù)據(jù)
x = df.日期
y = df.實際銷量

# 定義顏色
color1 = '#0085c3'
color2 = '#7ab800'
color3 = '#dc5034'

# 設(shè)置圖像大小
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111)

# 繪制折線圖
ax.plot(x, y, marker='o', color=color1)

# 標(biāo)注最大值
ax.text(x[y.idxmax()]+timedelta(hours=-12),
        y.max()+1, y.max(),
        color=color1, fontsize=15)

# 標(biāo)注最小值
ax.text(x[y.idxmin()]+timedelta(hours=-9),
        y.min()-2, y.min(),
        color=color1, fontsize=15)

# 計算 7 天移動平均
y2 = y.rolling(7).mean()

# 繪制趨勢線
ax.plot(x, y2, ls='--', color=color2, label='7 天移動平均')

# 繪制箭頭
plt.annotate('', xy=(x[-1:], y2[-1:]),
             xytext=(x[-2:-1], y2[-2:-1]),
             arrowprops=dict(arrowstyle='->',
                             color=color2,
                             shrinkB=0))

# 繪制平均值線
ax.hlines(y.mean(), x[0], x[-1:],
          linestyles='-.', colors=color3)

# 標(biāo)注平均值
ax.text(x[-1:]+timedelta(days=-7.5), y.mean()-2,
        '平均值: ' + str(round(y.mean(),1)),
        color=color3, fontsize=15)

# 標(biāo)注特殊事件
ax.annotate('中秋節(jié)', xy=(x[y.idxmin()], y.min()), color=color1,
             xytext=(x[y.idxmin()]+timedelta(days=1.5), y.min()-2),
             arrowprops=dict(arrowstyle='->', color=color1), fontsize=15)

ax.annotate('打折促銷', xy=(x[y.idxmax()], y.max()), color=color1,
             xytext=(x[y.idxmax()]+timedelta(days=-5), y.max()+2),
             arrowprops=dict(arrowstyle='->', color=color1), fontsize=15)

# 設(shè)置網(wǎng)格線
ax.grid(ls=':', color='gray', alpha=0.6)

# 設(shè)置圖例的位置和大小
ax.legend(loc='upper left', fontsize=12)

# 設(shè)置坐標(biāo)軸標(biāo)簽的角度和大小
plt.xticks(rotation=90, fontsize=12)
plt.yticks(fontsize=12)

# 設(shè)置 y 軸的刻度范圍
ax.set_ylim(0, y.max()+5)

# 設(shè)置圖表標(biāo)題
_ = ax.set_title('2019年9月每日銷量變化趨勢', fontsize=25)

學(xué)習(xí)來源

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容