【python科研绘图】封装接口直接利用DataFrame绘制百分比堆叠柱状图
封裝接口直接利用DataFrame繪制百分比柱狀圖
- 1. 背景前言
- 2. 官方網(wǎng)址示例
- 2.1 matplotlib_percentage_stacked_bar_plot
- 2.2 percent-stacked-barplot
- 2.3 Discrete distribution as horizontal bar chart
- 3. 問(wèn)題解決
- 3.1 全部代碼
- 3.2 代碼試錯(cuò)
- 4. 實(shí)操檢驗(yàn)
- 4.1 實(shí)操測(cè)試
- 4.2 更換標(biāo)簽
- 4.3 部分標(biāo)簽輸出
手動(dòng)反爬蟲:原博地址 https://editor.csdn.net/md/?articleId=106524459
知識(shí)梳理不易,請(qǐng)尊重勞動(dòng)成果,文章僅發(fā)布在CSDN網(wǎng)站上,在其他網(wǎng)站看到該博文均屬于未經(jīng)作者授權(quán)的惡意爬取信息本文為付費(fèi)內(nèi)容,禁止轉(zhuǎn)載
1. 背景前言
最近打比賽遇到的問(wèn)題有點(diǎn)多,在繪制了堆疊柱狀圖之后,隊(duì)長(zhǎng)說(shuō)不僅要看到具體的數(shù)量多少的堆疊圖,還要看到具體占比的百分比柱狀圖,具體的樣例可參考靈魂畫圖,因此也就產(chǎn)生了繪制百分比柱狀圖的需求
2. 官方網(wǎng)址示例
2.1 matplotlib_percentage_stacked_bar_plot
示例網(wǎng)址1
里面的代碼是真的長(zhǎng),完全屬于一步步進(jìn)行“堆磚塊”然后才形成的百分比堆疊圖,最終得出圖結(jié)果如下:
2.2 percent-stacked-barplot
示例網(wǎng)址2
這個(gè)網(wǎng)址給出的代碼比第一個(gè)網(wǎng)址給出的較為簡(jiǎn)潔,但是本質(zhì)上都是屬于一個(gè)個(gè)“磚塊”的疊加,代碼及生成的示例圖形如下:
# 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()→ 輸出的結(jié)果為:(這個(gè)結(jié)果相對(duì)好一點(diǎn))
2.3 Discrete distribution as horizontal bar chart
示例網(wǎng)址3
官方給出的示例圖是下面這樣的,看的第一眼是非常符合自己的要求的,而且還有不同的配色以及主題的標(biāo)簽設(shè)置及文本文字標(biāo)注
接著就看一下給出的源碼,如下,代碼封裝的挺不錯(cuò)的,還有可以直接調(diào)用的函數(shù),按照官方示例的代碼運(yùn)行后的確可以實(shí)現(xiàn)上方的圖形效果(內(nèi)心狂喜~~ )
這個(gè)官方給出的代碼,看似可以解決問(wèn)題,但是直接調(diào)用之后發(fā)現(xiàn),并不是百分比柱狀圖的結(jié)果,比如這里將數(shù)據(jù)稍作修改,更改數(shù)據(jù)如下,然后再運(yùn)行代碼
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后面加個(gè)0 }→ 輸出的結(jié)果為:(實(shí)際上這個(gè)圖本身就不是百分比堆疊柱狀圖,根據(jù)官方的名稱是離散分布的水平柱形圖)
然后百度搜索相關(guān)的python繪制的百分比堆疊柱狀圖基本上都是進(jìn)行一個(gè)個(gè)“壘砌”的,看到百度搜索返回的第一個(gè)結(jié)果,竟然把這個(gè)官方的示例聲稱為自己封裝的函數(shù),標(biāo)題還是繪制百分比柱狀圖,誤導(dǎo)讀者(本人也是被忽悠了,直到看到官網(wǎng)示例和實(shí)際調(diào)試)
3. 問(wèn)題解決
既然沒(méi)有現(xiàn)成的可以直接copy的代碼,而且也沒(méi)有像繪制堆疊圖時(shí)候直接就擁有stacked的參數(shù),所以就必須自己手動(dòng)整理了。前面的第三個(gè)示例代碼的框架可以直接拿過(guò)來(lái)用,就不用再進(jìn)行編寫了,只需要修改部分內(nèi)容即可
3.1 全部代碼
仿照之前的代碼形式,進(jìn)行代碼改寫,只需要傳入DataFrame數(shù)據(jù)即可,如下
def percentage_bar(df):labels = df.index.tolist() #提取分類顯示標(biāo)簽results = df.to_dict(orient = 'list') #將數(shù)值結(jié)果轉(zhuǎn)化為字典category_names = list(results.keys()) # 提取字典里面的類別(鍵-key)data = np.array(list(results.values())) #提取字典里面的數(shù)值(值-value)category_colors = plt.get_cmap('RdYlGn')(np.linspace(0.15, 0.85, data.shape[0])) #設(shè)置占比顯示的顏色,可以自定義,修改括號(hào)里面的參數(shù)即可,如下#category_colors = plt.get_cmap('hot')(np.linspace(0.15, 0.85, data.shape[0]))fig, ax = plt.subplots(figsize=(12, 9)) #創(chuàng)建畫布,開(kāi)始繪圖ax.invert_xaxis()#這個(gè)可以通過(guò)設(shè)置df中columns的順序調(diào)整ax.yaxis.set_visible(False) #設(shè)置y軸刻度不可見(jiàn)ax.set_xticklabels(labels=labels, rotation=90) #顯示x軸標(biāo)簽,并旋轉(zhuǎn)90度ax.set_ylim(0,1) #設(shè)置y軸的顯示范圍starts = 0 #繪制基準(zhǔn)for i, (colname, color) in enumerate(zip(category_names, category_colors)):heights = data[i,: ]/ data.sum(axis =0) #計(jì)算出每次遍歷時(shí)候的百分比ax.bar(labels, heights, bottom=starts, width=0.5,label=colname, color=color,edgecolor ='gray') # 繪制柱狀圖xcenters = starts + heights/2 #進(jìn)行文本標(biāo)記位置的選定starts += heights #核心一步,就是基于基準(zhǔn)上的百分比累加#print(starts) 這個(gè)變量就是能否百分比顯示的關(guān)鍵,可以打印輸出看一下percentage_text = data[i,: ]/ data.sum(axis =0) #文本標(biāo)記的數(shù)據(jù)r, g, b, _ = color # 這里進(jìn)行像素的分割text_color = 'white' if r * g * b < 0.5 else 'k' #根據(jù)顏色基調(diào)分配文本標(biāo)記的顏色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) #添加文本標(biāo)記ax.legend(ncol=len(category_names), bbox_to_anchor=(0, 1),loc='lower left', fontsize='large') #設(shè)置圖例return fig, ax #返回圖像比如把剛剛示例中的數(shù)據(jù)轉(zhuǎn)化為DataFrame數(shù)據(jù),如下
然后將df作為參數(shù)直接傳遞到percentage_bar函數(shù)中,看看結(jié)果輸出,內(nèi)部雖然設(shè)置x軸標(biāo)簽旋轉(zhuǎn)90度,但是在函數(shù)外邊還是可以直接調(diào)整其方向,這里就是取消旋轉(zhuǎn)了,而且在最后的文本標(biāo)記中采用的是百分比進(jìn)行進(jìn)標(biāo)注的,這樣更能清晰的明確各方的占比情況
3.2 代碼試錯(cuò)
還是和最初一樣,在最后一行數(shù)據(jù)的19后面添加一個(gè)0,變成190,這里順帶將y軸的刻度范圍調(diào)整為(0,1.1),來(lái)查看是否符合百分比的要求,然后執(zhí)行代碼及輸出結(jié)果如下
4. 實(shí)操檢驗(yàn)
上面已經(jīng)對(duì)函數(shù)進(jìn)行了試錯(cuò),無(wú)誤后直接將函數(shù)放置到自己自定義的第三方模塊下,方便自己調(diào)用,關(guān)于這步的操作,可以參考博客將自定義常用的一些函數(shù)封裝成可以直接調(diào)用的模塊方法
4.1 實(shí)操測(cè)試
4.2 更換標(biāo)簽
如果需要更換標(biāo)簽顯示(df的標(biāo)簽與列標(biāo)題互換),只需要將df轉(zhuǎn)置即可,如下
4.3 部分標(biāo)簽輸出
如果需要輸出部分的標(biāo)簽,可以直接對(duì)df的columns進(jìn)行切片即可(如果更換標(biāo)簽index轉(zhuǎn)置之后也是同理),輸出如下,比如這里只取兩個(gè)標(biāo)簽
最后,梳理不易,碼字分享希望能夠幫助大家。
總結(jié)
以上是生活随笔為你收集整理的【python科研绘图】封装接口直接利用DataFrame绘制百分比堆叠柱状图的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 计算机网络孙家启,孙家华
- 下一篇: 《与时间做朋友》读书笔记