瀑布圖有什麼用?用python怎麼畫?

  • 2020 年 3 月 18 日
  • 筆記

瀑布圖,因為形似瀑布而得名,它能夠比較好地體現數據分析的對比思維和細分思維。

比如說,假設某公司一月份銷售額 1000 萬,二月份銷售額 500 萬,為了體現各地區的銷售額變化,我們可以畫一張瀑布圖如下。

通過對比,發現銷售額下降了 50%;通過細分,發現不同地區的銷售變化差異較大,其中上海地區的銷售額增加了 30 萬,湖北地區的銷售額下降了 150 萬,其他地區的銷售額也都有不同程度的下降。

你可能會問,銷售額增加的原因是什麼?銷售額下降的原因又是什麼?這些都需要根據業務的實際情況,具體問題具體分析,找到問題的本質原因,從而有針對性地提出解決問題的辦法,本文給出的數據完全是虛擬的,所以這裡不做進一步的分析。

本文的重點,是介紹怎麼使用 Python 畫出瀑布圖,讓你能夠舉一反三,應用於自己的實際工作當中。你只需要把數據文件準備好,然後運行一遍程式碼,就能自動生成所需的瀑布圖。

1. 讀取數據

首先,我們導入所需的庫,並從 Excel 文件中讀取不同地區的銷售額數據。

# 導入所需的庫  import pandas as pd  import numpy as np  import matplotlib.pyplot as plt    # 設置正常顯示中文標籤  plt.rcParams['font.sans-serif'] = ['SimHei']    ########## 準備繪圖數據 ###############    # 從 Excel 文件中讀取數據,第一列設置為索引  sale = pd.read_excel('data/不同地區的銷售額變化.xlsx', index_col=0)    sale

2. 處理數據

其次,我們對原始數據進行處理,把數據轉換成繪圖所需的格式。

######### 處理數據 ###############    # 計算銷售額的變化  sale['銷售變化'] = sale.iloc[:, 1] - sale.iloc[:, 0]    # 把銷售匯總作為第一行  change = pd.concat([pd.DataFrame(sale.sum()).T, sale])    # 修改第一行的索引名稱:上個月  change.rename(index={0: sale.columns[0]}, inplace=True)    # 設置瀑布圖的第一個數值  change.iloc[0, 2] = change.iloc[0, 0]    # 排除沒有變化的項目  change = change[abs(change.銷售變化) > 0]    # 降序排列  change = change.sort_values('銷售變化', ascending=False)    # 不要包含匯總,後面會自動計算  index = change.index  data = change.銷售變化  trans = pd.DataFrame(data=data, index=index)    # 為瀑布圖創建空白序列,用於把柱子撐起來  blank = trans.銷售變化.cumsum().shift(1).fillna(0)    # 計算瀑布圖的最後一個數值:當月收入  thismonth = sale.columns[1]  total = trans.sum().銷售變化    # 設置瀑布圖中每個項目的變化  step = blank.reset_index(drop=True).repeat(3).shift(-1)  step[1::3] = np.nan    # 最後一根柱子是從 0 開始  blank.loc[thismonth] = 0  trans.loc[thismonth] = total    trans

3. 開始畫圖

接下來,我們開始畫圖,在畫圖函數所使用的數據中,trans 存儲的是瀑布圖中柱子對應的數據,blank 存儲的是柱子底端的高度數據。

import numpy as np  import pandas as pd  import matplotlib.pyplot as plt  from datetime import timedelta    # 正常顯示中文標籤  plt.rcParams['font.sans-serif'] = ['SimHei']    # 正常顯示負號  plt.rcParams['axes.unicode_minus'] = False    # 讀取每日銷售數據  df = pd.read_excel('./data/2019年9月每日銷售.xlsx')    # 定義畫圖的數據  x = df.日期  y = df.實際銷量    # 定義顏色  color1 = '#0085c3'  color2 = '#7ab800'  color3 = '#dc5034'    # 設置影像大小  ########## 開始畫圖 ###############    # 設置標題  title = 'n各地區銷售額變化瀑布圖n'    # 使用 Pandas 中的畫圖函數  waterfall = trans.plot(kind='bar', stacked=True, bottom=blank, legend=None, figsize=(16, 8), fontsize=20, width=0.8)    # 設置 x 軸標籤  waterfall.set_xlabel("")    # 計算標籤位置的偏移量  max = trans.max()  neg_offset = max / 25  pos_offset = max / 50  plot_offset = int(max / 10)    # 獲取標籤的高度位置  y_height = trans.銷售變化.cumsum().shift(1).fillna(0)    # 循環設置標籤  loop = 0  for index, row in trans.iterrows():      x = row['銷售變化']      # 最後一個標籤的位置不要雙倍      if x == total:          y = y_height[loop]      else:          y = y_height[loop] + x        # 決定向上還是向下偏移      if x > 0:          y += pos_offset      else:          y -= neg_offset        # 添加數字標籤,負數用紅色      waterfall.annotate("{:.1f}".format(x), (loop, y), ha="center", fontsize=20, color=('k' if x>0 else 'r'))      loop+=1    # 設置 y 軸的偏移量  waterfall.set_ylim(0, blank.max()+int(plot_offset))    # 設置 x 軸標籤的角度  waterfall.set_xticklabels(trans.index, rotation=0)    # 設置標題並顯示圖片  plt.title(title, fontsize=36, loc='center', color='k')    plt.show()

運行之後得到的圖片,就是本文開頭顯示的那張瀑布圖。

4. 小結

本文介紹了瀑布圖的一個應用案例,並給出了詳細的 Python 實現程式碼,在公眾號後台發送「瀑布」兩個字,可以獲得本文的數據文件和完整程式碼。

雖然 Excel 也能畫瀑布圖,但是我個人覺得用 Python 能夠更加靈活高效。

Python 能讓數據分析等工作變得更加自動化、標準化、流程化。

所以,我漸漸地把很多工作,都轉換為使用 Python 來完成,以提升自己的工作效率和工作品質,讓自己有時間去做更多更有價值的事情。

多花一些時間,去提升自己的能力,讓自己獲得成長和進步,我覺得是非常值得的,所謂「磨刀不誤砍柴工」,這也是我們要學習時間管理的重要原因之一。

最後再次重複一遍哈,在公眾號後台發送「瀑布」兩個字,可以獲得本文的數據文件和完整程式碼。