Python Excel數(shù)據(jù)可視化之柱狀圖繪制教程
?小張是公司里做運(yùn)營(yíng)分析的,每個(gè)月都要把銷售數(shù)據(jù)整理成圖表,給老板做匯報(bào)。以前他都是手動(dòng)在Excel里點(diǎn)來(lái)點(diǎn)去,選數(shù)據(jù)范圍、插入柱狀圖、調(diào)顏色、改字體,一套操作下來(lái)至少半小時(shí)。碰上數(shù)據(jù)更新頻繁的日子,他得重復(fù)做三四遍同樣的操作,煩到想摔鼠標(biāo)。
有一天他跑來(lái)問我:“有沒有辦法讓Excel自動(dòng)畫圖?我每次數(shù)據(jù)格式都一樣,就是數(shù)值變了。”
我說(shuō):“用Python啊,寫一次腳本,以后一鍵生成,顏色字體你說(shuō)了算,還能批量處理。”
他眼睛亮了。
這篇文章就從這個(gè)場(chǎng)景出發(fā),聊聊怎么用Python和Excel配合,優(yōu)雅地畫出各種柱狀圖。
準(zhǔn)備工具,裝三個(gè)庫(kù)就夠了
Python操作Excel有幾個(gè)成熟的庫(kù)。最省事的是pandas,它能直接讀寫Excel文件,處理數(shù)據(jù)表格。畫圖交給matplotlib,這個(gè)庫(kù)幾乎能畫出所有你能想象到的圖表。如果還想保留Excel公式或者調(diào)整格式,可以加上openpyxl。
裝起來(lái)一句話的事情:
pip install pandas matplotlib openpyxl
我習(xí)慣在Jupyter Notebook里調(diào)試這些代碼,因?yàn)槟芸吹矫恳徊降臄?shù)據(jù)長(zhǎng)什么樣。如果你用普通.py文件也完全沒問題。
拿數(shù)據(jù)開刀,從Excel讀到pandas
先看一個(gè)實(shí)際場(chǎng)景。假設(shè)有一張銷售數(shù)據(jù)表叫sales.xlsx,里面每個(gè)月每個(gè)產(chǎn)品的銷售額:
| 月份 | 產(chǎn)品A | 產(chǎn)品B | 產(chǎn)品C |
|---|---|---|---|
| 1月 | 120 | 95 | 80 |
| 2月 | 135 | 102 | 88 |
| 3月 | 148 | 110 | 92 |
用pandas讀這個(gè)文件只需要一行:
import pandas as pd
df = pd.read_excel('sales.xlsx')
print(df.head())
head()方法能讓你看一眼前幾行數(shù)據(jù),確認(rèn)讀進(jìn)來(lái)的格式對(duì)不對(duì)。pandas會(huì)自動(dòng)把第一行當(dāng)作列名,后面每一行對(duì)應(yīng)一個(gè)月份。
第一張柱狀圖,五步搞定
數(shù)據(jù)在手里了,畫圖其實(shí)就五步:選數(shù)據(jù)、創(chuàng)建畫布、畫柱狀圖、加標(biāo)題標(biāo)簽、顯示或保存。
import matplotlib.pyplot as plt
# 把月份列作為橫坐標(biāo)的標(biāo)簽
months = df['月份']
# 遍歷每一列產(chǎn)品,分別畫一組柱子
plt.bar(months, df['產(chǎn)品A'], label='產(chǎn)品A')
plt.bar(months, df['產(chǎn)品B'], label='產(chǎn)品B')
plt.bar(months, df['產(chǎn)品C'], label='產(chǎn)品C')
# 加標(biāo)簽和標(biāo)題
plt.xlabel('月份')
plt.ylabel('銷售額(萬(wàn)元)')
plt.title('各產(chǎn)品月度銷售對(duì)比')
# 顯示圖例
plt.legend()
# 展示圖表
plt.show()
跑完這段代碼,一張簡(jiǎn)單的分組柱狀圖就彈出來(lái)了。每個(gè)月份有三根柱子并排,代表三個(gè)產(chǎn)品的銷售額。
這比在Excel里手動(dòng)選區(qū)域、插入圖表快多了。但還不夠好看,柱子顏色、字體大小、網(wǎng)格線都可以調(diào)。
讓圖表好看一點(diǎn),細(xì)節(jié)決定質(zhì)感
默認(rèn)的matplotlib圖表長(zhǎng)得很“學(xué)術(shù)”,藍(lán)橘色的柱子,白色背景,談不上難看但也說(shuō)不上精致。改幾個(gè)參數(shù)就能大變樣。
# 設(shè)置中文字體,不然圖表里的中文會(huì)變成方框
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 創(chuàng)建畫布時(shí)指定尺寸和分辨率
fig, ax = plt.subplots(figsize=(10, 6), dpi=100)
# 畫圖時(shí)自定義顏色和透明度
ax.bar(months, df['產(chǎn)品A'], label='產(chǎn)品A', color='#FF6B6B', alpha=0.8)
ax.bar(months, df['產(chǎn)品B'], label='產(chǎn)品B', color='#4ECDC4', alpha=0.8)
ax.bar(months, df['產(chǎn)品C'], label='產(chǎn)品C', color='#45B7D1', alpha=0.8)
# 添加網(wǎng)格線,提升可讀性
ax.grid(axis='y', linestyle='--', alpha=0.5)
# 在柱子上方顯示數(shù)值
for i, (a, b, c) in enumerate(zip(df['產(chǎn)品A'], df['產(chǎn)品B'], df['產(chǎn)品C'])):
ax.text(i, a + 2, str(a), ha='center', va='bottom', fontsize=9)
ax.text(i, b + 2, str(b), ha='center', va='bottom', fontsize=9)
ax.text(i, c + 2, str(c), ha='center', va='bottom', fontsize=9)
plt.tight_layout()
plt.show()
alpha參數(shù)控制透明度,多個(gè)柱子重疊時(shí)能看到后面的內(nèi)容。grid加網(wǎng)格線能讓數(shù)值對(duì)比更直觀。text方法在柱子上方標(biāo)了具體數(shù)字,老板看圖表時(shí)不用再猜這根柱子到底是多少。
顏色代碼用的是十六進(jìn)制RGB格式,比默認(rèn)的顏色高級(jí)不少。可以在網(wǎng)上搜配色方案,選一套自己看著舒服的。
兩種特殊柱狀圖,應(yīng)付不同場(chǎng)景
有時(shí)候并排柱子太多了,顯得擁擠??梢該Q成堆疊柱狀圖,每個(gè)月份的三根柱子疊在一起,總高度就是三個(gè)產(chǎn)品的銷售額之和。
# 堆疊柱狀圖
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(months, df['產(chǎn)品A'], label='產(chǎn)品A', color='#FF6B6B')
ax.bar(months, df['產(chǎn)品B'], bottom=df['產(chǎn)品A'], label='產(chǎn)品B', color='#4ECDC4')
ax.bar(months, df['產(chǎn)品C'], bottom=df['產(chǎn)品A'] + df['產(chǎn)品B'], label='產(chǎn)品C', color='#45B7D1')
ax.set_ylabel('總銷售額(萬(wàn)元)')
ax.legend()
plt.show()
bottom參數(shù)決定了這根柱子從哪里開始堆疊。產(chǎn)品B的柱子底端是產(chǎn)品A的高度,產(chǎn)品C的柱子底端是A加B的高度。這種圖適合展示“總量”和“構(gòu)成”的關(guān)系。
還有一種需求是橫向柱狀圖。當(dāng)產(chǎn)品名稱或者月份標(biāo)簽比較長(zhǎng)時(shí),豎著放會(huì)擠在一起看不清。barh方法畫橫著的版本:
# 橫向柱狀圖 ax.barh(months, df['產(chǎn)品A'], label='產(chǎn)品A') ax.barh(months, df['產(chǎn)品B'], label='產(chǎn)品B') ax.barh(months, df['產(chǎn)品C'], label='產(chǎn)品C')
只是把bar換成了barh,x軸和y軸的角色互換了。
批量生成圖表,十分鐘的工作變成十秒鐘
這才是Python真正的殺手锏。假設(shè)你有12個(gè)分公司的銷售數(shù)據(jù),分別存在12個(gè)Excel文件里,每個(gè)文件要生成一張柱狀圖。手動(dòng)做的話,打開、復(fù)制、粘貼、調(diào)整格式,一上午就沒了。
用Python寫個(gè)循環(huán),幾秒鐘跑完。
import glob
# 獲取所有Excel文件
files = glob.glob('分公司銷售數(shù)據(jù)/*.xlsx')
for file in files:
df = pd.read_excel(file)
# 從文件名提取分公司名稱,用來(lái)命名輸出的圖片
company_name = file.split('/')[-1].replace('.xlsx', '')
fig, ax = plt.subplots(figsize=(10, 6))
ax.bar(df['月份'], df['銷售額'], color='steelblue')
ax.set_title(f'{company_name}月度銷售情況')
ax.set_xlabel('月份')
ax.set_ylabel('銷售額(萬(wàn)元)')
# 不顯示窗口,直接保存文件
plt.savefig(f'圖表輸出/{company_name}_柱狀圖.png', dpi=150, bbox_inches='tight')
plt.close()
這里有兩個(gè)關(guān)鍵點(diǎn)。savefig代替show,不彈窗口直接存圖。bbox_inches='tight'能自動(dòng)裁剪掉圖表周圍多余的空白。循環(huán)結(jié)束后,指定文件夾里整整齊齊躺著12張圖片,每一張都格式統(tǒng)一、標(biāo)題自動(dòng)適配。
把圖表寫回Excel,方便分享
有些人不想單獨(dú)看圖片文件,希望圖表直接嵌入到Excel表格里。這也能做到,用openpyxl配合matplotlib。
from openpyxl import Workbook
from openpyxl.utils.dataframe import dataframe_to_rows
from openpyxl.drawing.image import Image
import io
# 先把圖表存到內(nèi)存里的字節(jié)流,不生成臨時(shí)文件
buf = io.BytesIO()
plt.savefig(buf, format='png', dpi=100)
buf.seek(0)
# 新建Excel文件并寫入數(shù)據(jù)
wb = Workbook()
ws = wb.active
# 將pandas數(shù)據(jù)寫入工作表
for r in dataframe_to_rows(df, index=False, header=True):
ws.append(r)
# 插入圖片
img = Image(buf)
img.width = 400
img.height = 300
ws.add_image(img, 'E2') # 放在E2單元格位置
wb.save('帶圖表的銷售報(bào)表.xlsx')
這樣生成的文件,別人打開就能直接看到數(shù)據(jù)和圖表,不需要額外發(fā)圖片。
幾個(gè)讓我踩過(guò)坑的小問題
中文字體是最容易翻車的。matplotlib默認(rèn)字體不支持中文,畫出來(lái)的圖里漢字全是小方框。解決方案是提前設(shè)置字體,用rcParams指定一個(gè)系統(tǒng)中存在的支持中文的字體。如果是在Linux服務(wù)器上跑,可能需要先安裝中文字體,或者用fc-list :lang=zh命令查一下已安裝的字體。
數(shù)據(jù)列名不要有空格。pandas讀取Excel后,如果列名是“產(chǎn)品 A”這種帶空格的,調(diào)用df['產(chǎn)品 A']會(huì)報(bào)錯(cuò)。要么提前改好列名,要么用df.columns = [col.strip() for col in df.columns]批量清理。
保存圖表時(shí)如果中文變成了亂碼,試試plt.savefig之前再加一次字體設(shè)置。有時(shí)候前面設(shè)好了,保存時(shí)卻丟失了,重新設(shè)置能解決。
從手動(dòng)到自動(dòng),效率提升看得見
小張后來(lái)用這套腳本,每月做報(bào)表的時(shí)間從半小時(shí)壓縮到了十秒鐘。他只需要把最新的數(shù)據(jù)覆蓋到Excel文件里,雙擊運(yùn)行腳本,圖表自動(dòng)生成。他把腳本給了部門其他同事,大家都很開心。
數(shù)據(jù)可視化的核心價(jià)值不是圖表多漂亮,而是能不能快速準(zhǔn)確地傳達(dá)信息。當(dāng)你重復(fù)做同一類圖表超過(guò)三次,就該考慮寫腳本了。這不是偷懶,是聰明地工作。
Excel和Python不是替代關(guān)系,是互補(bǔ)關(guān)系。Excel適合交互式探索數(shù)據(jù),Python適合批量化、自動(dòng)化處理。兩者結(jié)合,威力翻倍。
以上就是Python Excel數(shù)據(jù)可視化之柱狀圖繪制教程的詳細(xì)內(nèi)容,更多關(guān)于Python Excel數(shù)據(jù)可視化的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
python實(shí)現(xiàn)簡(jiǎn)易通訊錄修改版
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)簡(jiǎn)易通訊錄的修改版,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-03-03
Python實(shí)現(xiàn)計(jì)算對(duì)象的內(nèi)存大小示例
這篇文章主要介紹了Python實(shí)現(xiàn)計(jì)算對(duì)象的內(nèi)存大小,結(jié)合實(shí)例形式分析了Python使用sys.getsizeof與遞歸算法計(jì)算對(duì)象占用內(nèi)存的相關(guān)操作技巧,需要的朋友可以參考下2019-07-07
Python通過(guò)Pillow實(shí)現(xiàn)圖片對(duì)比
這篇文章主要介紹了Python Pillow實(shí)現(xiàn)圖片對(duì)比,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04
python代碼實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了python代碼實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-05-05
pytorch加載預(yù)訓(xùn)練模型與自己模型不匹配的解決方案
這篇文章主要介紹了pytorch加載預(yù)訓(xùn)練模型與自己模型不匹配的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-05-05
Python中調(diào)用C++代碼的方法總結(jié)
這篇文章主要為大家詳細(xì)介紹了Python中調(diào)用C++代碼的相關(guān)方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下2025-11-11
解決TensorFlow模型恢復(fù)報(bào)錯(cuò)的問題
今天小編就為大家分享一篇解決TensorFlow模型恢復(fù)報(bào)錯(cuò)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02

