【python科研绘图】封装接口直接利用DataFrame绘制百分比堆叠柱状图
封裝接口直接利用DataFrame繪制百分比柱狀圖
- 1. 背景前言
- 2. 官方網址示例
- 2.1 matplotlib_percentage_stacked_bar_plot
- 2.2 percent-stacked-barplot
- 2.3 Discrete distribution as horizontal bar chart
- 3. 問題解決
- 3.1 全部代碼
- 3.2 代碼試錯
- 4. 實操檢驗
- 4.1 實操測試
- 4.2 更換標簽
- 4.3 部分標簽輸出
手動反爬蟲:原博地址 https://editor.csdn.net/md/?articleId=106524459
知識梳理不易,請尊重勞動成果,文章僅發布在CSDN網站上,在其他網站看到該博文均屬于未經作者授權的惡意爬取信息本文為付費內容,禁止轉載
1. 背景前言
最近打比賽遇到的問題有點多,在繪制了堆疊柱狀圖之后,隊長說不僅要看到具體的數量多少的堆疊圖,還要看到具體占比的百分比柱狀圖,具體的樣例可參考靈魂畫圖,因此也就產生了繪制百分比柱狀圖的需求
2. 官方網址示例
2.1 matplotlib_percentage_stacked_bar_plot
示例網址1
里面的代碼是真的長,完全屬于一步步進行“堆磚塊”然后才形成的百分比堆疊圖,最終得出圖結果如下:
2.2 percent-stacked-barplot
示例網址2
這個網址給出的代碼比第一個網址給出的較為簡潔,但是本質上都是屬于一個個“磚塊”的疊加,代碼及生成的示例圖形如下:
# libraries import numpy as np import matplotlib.pyplot as plt from matplotlib import rc import pandas as pd# Data r = [0,1,2,3,4] raw_data = {'greenBars': [20, 1.5, 7, 10, 5], 'orangeBars': [5, 15, 5, 10, 15],'blueBars': [2, 15, 18, 5, 10]} df = pd.DataFrame(raw_data)# From raw value to percentage totals = [i+j+k for i,j,k in zip(df['greenBars'], df['orangeBars'], df['blueBars'])] greenBars = [i / j * 100 for i,j in zip(df['greenBars'], totals)] orangeBars = [i / j * 100 for i,j in zip(df['orangeBars'], totals)] blueBars = [i / j * 100 for i,j in zip(df['blueBars'], totals)]# plot barWidth = 0.85 names = ('A','B','C','D','E') # Create green Bars plt.bar(r, greenBars, color='#b5ffb9', edgecolor='white', width=barWidth) # Create orange Bars plt.bar(r, orangeBars, bottom=greenBars, color='#f9bc86', edgecolor='white', width=barWidth) # Create blue Bars plt.bar(r, blueBars, bottom=[i+j for i,j in zip(greenBars, orangeBars)], color='#a3acff', edgecolor='white', width=barWidth)# Custom x axis plt.xticks(r, names) plt.xlabel("group")# Show graphic plt.show()→ 輸出的結果為:(這個結果相對好一點)
2.3 Discrete distribution as horizontal bar chart
示例網址3
官方給出的示例圖是下面這樣的,看的第一眼是非常符合自己的要求的,而且還有不同的配色以及主題的標簽設置及文本文字標注
接著就看一下給出的源碼,如下,代碼封裝的挺不錯的,還有可以直接調用的函數,按照官方示例的代碼運行后的確可以實現上方的圖形效果(內心狂喜~~ )
這個官方給出的代碼,看似可以解決問題,但是直接調用之后發現,并不是百分比柱狀圖的結果,比如這里將數據稍作修改,更改數據如下,然后再運行代碼
results = {'Question 1': [10, 15, 17, 32, 26],'Question 2': [26, 22, 29, 10, 13],'Question 3': [35, 37, 7, 2, 19],'Question 4': [32, 11, 9, 15, 33],'Question 5': [21, 29, 5, 5, 40],'Question 6': [8, 190, 5, 30, 38] #在19后面加個0 }→ 輸出的結果為:(實際上這個圖本身就不是百分比堆疊柱狀圖,根據官方的名稱是離散分布的水平柱形圖)
然后百度搜索相關的python繪制的百分比堆疊柱狀圖基本上都是進行一個個“壘砌”的,看到百度搜索返回的第一個結果,竟然把這個官方的示例聲稱為自己封裝的函數,標題還是繪制百分比柱狀圖,誤導讀者(本人也是被忽悠了,直到看到官網示例和實際調試)
3. 問題解決
既然沒有現成的可以直接copy的代碼,而且也沒有像繪制堆疊圖時候直接就擁有stacked的參數,所以就必須自己手動整理了。前面的第三個示例代碼的框架可以直接拿過來用,就不用再進行編寫了,只需要修改部分內容即可
3.1 全部代碼
仿照之前的代碼形式,進行代碼改寫,只需要傳入DataFrame數據即可,如下
def percentage_bar(df):labels = df.index.tolist() #提取分類顯示標簽results = df.to_dict(orient = 'list') #將數值結果轉化為字典category_names = list(results.keys()) # 提取字典里面的類別(鍵-key)data = np.array(list(results.values())) #提取字典里面的數值(值-value)category_colors = plt.get_cmap('RdYlGn')(np.linspace(0.15, 0.85, data.shape[0])) #設置占比顯示的顏色,可以自定義,修改括號里面的參數即可,如下#category_colors = plt.get_cmap('hot')(np.linspace(0.15, 0.85, data.shape[0]))fig, ax = plt.subplots(figsize=(12, 9)) #創建畫布,開始繪圖ax.invert_xaxis()#這個可以通過設置df中columns的順序調整ax.yaxis.set_visible(False) #設置y軸刻度不可見ax.set_xticklabels(labels=labels, rotation=90) #顯示x軸標簽,并旋轉90度ax.set_ylim(0,1) #設置y軸的顯示范圍starts = 0 #繪制基準for i, (colname, color) in enumerate(zip(category_names, category_colors)):heights = data[i,: ]/ data.sum(axis =0) #計算出每次遍歷時候的百分比ax.bar(labels, heights, bottom=starts, width=0.5,label=colname, color=color,edgecolor ='gray') # 繪制柱狀圖xcenters = starts + heights/2 #進行文本標記位置的選定starts += heights #核心一步,就是基于基準上的百分比累加#print(starts) 這個變量就是能否百分比顯示的關鍵,可以打印輸出看一下percentage_text = data[i,: ]/ data.sum(axis =0) #文本標記的數據r, g, b, _ = color # 這里進行像素的分割text_color = 'white' if r * g * b < 0.5 else 'k' #根據顏色基調分配文本標記的顏色for y, (x, c) in enumerate(zip(xcenters, percentage_text)):ax.text(y, x, f'{round(c*100,2)}%', ha='center', va='center',color=text_color, rotation = 90) #添加文本標記ax.legend(ncol=len(category_names), bbox_to_anchor=(0, 1),loc='lower left', fontsize='large') #設置圖例return fig, ax #返回圖像比如把剛剛示例中的數據轉化為DataFrame數據,如下
然后將df作為參數直接傳遞到percentage_bar函數中,看看結果輸出,內部雖然設置x軸標簽旋轉90度,但是在函數外邊還是可以直接調整其方向,這里就是取消旋轉了,而且在最后的文本標記中采用的是百分比進行進標注的,這樣更能清晰的明確各方的占比情況
3.2 代碼試錯
還是和最初一樣,在最后一行數據的19后面添加一個0,變成190,這里順帶將y軸的刻度范圍調整為(0,1.1),來查看是否符合百分比的要求,然后執行代碼及輸出結果如下
4. 實操檢驗
上面已經對函數進行了試錯,無誤后直接將函數放置到自己自定義的第三方模塊下,方便自己調用,關于這步的操作,可以參考博客將自定義常用的一些函數封裝成可以直接調用的模塊方法
4.1 實操測試
4.2 更換標簽
如果需要更換標簽顯示(df的標簽與列標題互換),只需要將df轉置即可,如下
4.3 部分標簽輸出
如果需要輸出部分的標簽,可以直接對df的columns進行切片即可(如果更換標簽index轉置之后也是同理),輸出如下,比如這里只取兩個標簽
最后,梳理不易,碼字分享希望能夠幫助大家。
總結
以上是生活随笔為你收集整理的【python科研绘图】封装接口直接利用DataFrame绘制百分比堆叠柱状图的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机网络孙家启,孙家华
- 下一篇: Python画饼状图解决字体重叠问题