瀑布圖有什麼用?用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 來完成,以提升自己的工作效率和工作品質,讓自己有時間去做更多更有價值的事情。
多花一些時間,去提升自己的能力,讓自己獲得成長和進步,我覺得是非常值得的,所謂「磨刀不誤砍柴工」,這也是我們要學習時間管理的重要原因之一。
最後再次重複一遍哈,在公眾號後台發送「瀑布」兩個字,可以獲得本文的數據文件和完整程式碼。