Python使用Matplotlib將爬取的CSV數(shù)據(jù)變成直觀圖表
引言:為什么需要數(shù)據(jù)可視化?
當(dāng)你在電商網(wǎng)站爬取了10萬條商品價(jià)格數(shù)據(jù),或是從氣象站抓取了3年的溫度記錄,面對(duì)密密麻麻的CSV表格時(shí),是否感到無從下手?這時(shí)候,數(shù)據(jù)可視化就像給數(shù)據(jù)裝上了一副"透 視鏡",能讓你一眼看穿數(shù)據(jù)背后的規(guī)律。
本文將帶你完成一個(gè)完整的數(shù)據(jù)可視化實(shí)戰(zhàn):從爬取某招聘網(wǎng)站的職位信息,到用Matplotlib生成專業(yè)圖表。不需要數(shù)學(xué)博士背景,只需跟著步驟操作,你就能做出讓同事驚嘆的可視化報(bào)告。
一、準(zhǔn)備階段:環(huán)境搭建與數(shù)據(jù)獲取
1.1 基礎(chǔ)環(huán)境配置
首先確保你的Python環(huán)境已安裝必要的庫:
pip install matplotlib pandas requests beautifulsoup4
這四個(gè)庫的分工很明確:
requests:負(fù)責(zé)發(fā)送HTTP請(qǐng)求獲取網(wǎng)頁BeautifulSoup4:解析HTML提取數(shù)據(jù)pandas:處理CSV數(shù)據(jù)matplotlib:繪制可視化圖表
1.2 爬取示例數(shù)據(jù)
以某招聘網(wǎng)站為例,我們爬取Python開發(fā)崗位的薪資和城市分布數(shù)據(jù):
import requests
from bs4 import BeautifulSoup
import pandas as pd
def crawl_job_data():
headers = {'User-Agent': 'Mozilla/5.0'}
jobs = []
for page in range(1, 6): # 爬取前5頁
url = f"https://example.com/jobs?page={page}&keyword=Python"
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
# 假設(shè)每個(gè)職位在class為'job-item'的div中
for item in soup.find_all('div', class_='job-item'):
title = item.find('h2').text.strip()
salary = item.find('span', class_='salary').text.strip()
city = item.find('span', class_='location').text.strip()
jobs.append({'title': title, 'salary': salary, 'city': city})
df = pd.DataFrame(jobs)
df.to_csv('job_data.csv', index=False)
return df
data = crawl_job_data()提示:實(shí)際爬取時(shí)需遵守網(wǎng)站的robots協(xié)議,建議添加延遲(time.sleep(2))避免被封。
二、數(shù)據(jù)清洗:讓數(shù)據(jù)"干凈"起來
爬取的原始數(shù)據(jù)往往包含臟數(shù)據(jù),比如薪資字段可能包含"15-20K/月"這樣的文本。我們需要將其轉(zhuǎn)換為數(shù)值:
def clean_salary(salary_str):
try:
# 提取數(shù)字部分,例如"15-20K/月"→[15,20]
parts = salary_str.replace('K', '').replace('/月', '').split('-')
if len(parts) == 2:
return (float(parts[0]) + float(parts[1])) / 2 # 取平均值
return float(parts[0])
except:
return None
data['salary'] = data['salary'].apply(clean_salary)
data = data.dropna(subset=['salary']) # 刪除薪資為空的記錄對(duì)于城市字段,我們可能需要統(tǒng)計(jì)每個(gè)城市的職位數(shù)量:
city_counts = data['city'].value_counts().head(10) # 取前10個(gè)城市
三、基礎(chǔ)圖表制作:柱狀圖與折線圖
3.1 城市職位分布柱狀圖
柱狀圖最適合展示分類數(shù)據(jù)的對(duì)比:
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 6))
city_counts.plot(kind='bar', color='#4C72B0')
plt.title('Python崗位城市分布', fontsize=16)
plt.xlabel('城市', fontsize=12)
plt.ylabel('職位數(shù)量', fontsize=12)
plt.xticks(rotation=45) # 旋轉(zhuǎn)x軸標(biāo)簽
plt.grid(axis='y', linestyle='--', alpha=0.7)
# 在柱子上方顯示數(shù)值
for i, v in enumerate(city_counts):
plt.text(i, v + 50, str(v), ha='center')
plt.tight_layout() # 自動(dòng)調(diào)整布局
plt.savefig('city_distribution.png', dpi=300)
plt.show()效果說明:
- 藍(lán)色柱子高度代表職位數(shù)量
- 每個(gè)柱子上方顯示具體數(shù)值
- 網(wǎng)格線輔助讀數(shù)
- 圖片保存為300dpi高清圖
3.2 薪資趨勢折線圖
假設(shè)我們按經(jīng)驗(yàn)要求分組統(tǒng)計(jì)平均薪資:
# 假設(shè)數(shù)據(jù)中有'experience'字段
exp_salary = data.groupby('experience')['salary'].mean()
plt.figure(figsize=(10, 5))
exp_salary.plot(kind='line', marker='o', color='#DD8452')
plt.title('不同經(jīng)驗(yàn)要求的平均薪資', fontsize=14)
plt.xlabel('經(jīng)驗(yàn)要求', fontsize=11)
plt.ylabel('平均薪資(K)', fontsize=11)
plt.grid(True, linestyle=':', alpha=0.6)
# 標(biāo)記數(shù)據(jù)點(diǎn)
for x, y in zip(exp_salary.index, exp_salary):
plt.text(x, y, f'{y:.1f}K', ha='center', va='bottom')
plt.show()關(guān)鍵點(diǎn):
- 橙色折線連接各數(shù)據(jù)點(diǎn)
- 每個(gè)數(shù)據(jù)點(diǎn)上方顯示具體數(shù)值
- 虛線網(wǎng)格增強(qiáng)可讀性
四、進(jìn)階圖表:散點(diǎn)圖與餅圖
4.1 薪資與經(jīng)驗(yàn)相關(guān)性散點(diǎn)圖
探索薪資與工作經(jīng)驗(yàn)是否相關(guān):
# 假設(shè)我們隨機(jī)生成一些經(jīng)驗(yàn)?zāi)晗迶?shù)據(jù)
import numpy as np
np.random.seed(42)
data['experience_years'] = np.random.randint(1, 11, size=len(data))
plt.figure(figsize=(10, 8))
plt.scatter(data['experience_years'], data['salary'],
alpha=0.6, color='#55A868', s=50) # s控制點(diǎn)大小
plt.title('工作經(jīng)驗(yàn)與薪資關(guān)系', fontsize=15)
plt.xlabel('工作經(jīng)驗(yàn)(年)', fontsize=12)
plt.ylabel('薪資(K)', fontsize=12)
# 添加趨勢線
z = np.polyfit(data['experience_years'], data['salary'], 1)
p = np.poly1d(z)
plt.plot(data['experience_years'], p(data['experience_years']),
"r--", linewidth=1)
plt.grid(True)
plt.show()解讀:
- 綠色散點(diǎn)表示各個(gè)數(shù)據(jù)點(diǎn)
- 紅色虛線為線性趨勢線
- 透明度(alpha)設(shè)置避免點(diǎn)重疊
4.2 薪資范圍餅圖
展示不同薪資區(qū)間的職位占比:
# 創(chuàng)建薪資區(qū)間
bins = [0, 10, 15, 20, 30]
labels = ['10K以下', '10-15K', '15-20K', '20K以上']
data['salary_range'] = pd.cut(data['salary'], bins=bins, labels=labels)
range_counts = data['salary_range'].value_counts()
plt.figure(figsize=(8, 8))
plt.pie(range_counts, labels=range_counts.index,
autopct='%1.1f%%', startangle=90,
colors=['#C44E52', '#CCB974', '#64776D', '#798E87'])
plt.title('Python崗位薪資分布', fontsize=15)
plt.tight_layout()
plt.show()技巧:
autopct顯示百分比startangle控制起始角度- 自定義顏色讓圖表更美觀
五、多圖表組合:子圖與儀表盤
5.1 創(chuàng)建包含多個(gè)圖表的儀表盤
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('Python崗位數(shù)據(jù)分析儀表盤', fontsize=18)
# 子圖1:城市分布
axes[0,0].bar(city_counts.index, city_counts.values, color='#4C72B0')
axes[0,0].set_title('城市分布')
axes[0,0].tick_params(axis='x', rotation=45)
# 子圖2:經(jīng)驗(yàn)-薪資散點(diǎn)
axes[0,1].scatter(data['experience_years'], data['salary'],
alpha=0.5, color='#55A868')
axes[0,1].set_title('經(jīng)驗(yàn)與薪資關(guān)系')
# 子圖3:薪資范圍餅圖
axes[1,0].pie(range_counts, labels=None, autopct='%1.1f%%',
colors=['#C44E52', '#CCB974', '#64776D', '#798E87'])
axes[1,0].set_title('薪資分布')
# 子圖4:經(jīng)驗(yàn)要求折線圖
exp_salary.plot(kind='line', marker='o', ax=axes[1,1], color='#DD8452')
axes[1,1].set_title('經(jīng)驗(yàn)要求與平均薪資')
plt.tight_layout()
plt.subplots_adjust(top=0.92) # 調(diào)整標(biāo)題位置
plt.savefig('dashboard.png', dpi=300)
plt.show()優(yōu)勢:
- 單張圖片展示多個(gè)維度
- 適合放入分析報(bào)告
- 保持統(tǒng)一的風(fēng)格
六、樣式優(yōu)化:讓圖表更專業(yè)
6.1 全局樣式設(shè)置
plt.style.use('seaborn') # 使用seaborn樣式
# 或自定義樣式
plt.rcParams.update({
'font.family': 'Microsoft YaHei', # 中文支持
'axes.titlesize': 14,
'axes.labelsize': 12,
'xtick.labelsize': 10,
'ytick.labelsize': 10,
'figure.figsize': (10, 6),
'savefig.dpi': 300
})6.2 顏色搭配技巧
推薦使用以下配色方案:
- 分類數(shù)據(jù):
['#4C72B0', '#55A868', '#C44E52', '#CCB974'] - 連續(xù)數(shù)據(jù):
['#313695', '#4575b4', '#74add1', '#abd9e9']
可以使用在線工具Coolors生成配色方案。
七、實(shí)際應(yīng)用案例:電商價(jià)格監(jiān)控
假設(shè)我們爬取了某電商平臺(tái)的手機(jī)價(jià)格數(shù)據(jù):
# 模擬數(shù)據(jù)
phone_data = {
'brand': ['Apple']*5 + ['Samsung']*5 + ['Huawei']*5,
'model': ['iPhone13']*3 + ['iPhone13 Pro']*2 +
['S22']*3 + ['S22 Ultra']*2 +
['P50']*3 + ['Mate50']*2,
'price': [5999, 6799, 5499, 8999, 9799,
4999, 5499, 6299, 7999, 8999,
4499, 4999, 5299, 6799, 7499],
'rating': [4.8, 4.9, 4.7, 4.9, 4.8,
4.6, 4.7, 4.8, 4.9, 4.8,
4.5, 4.6, 4.7, 4.8, 4.7]
}
df = pd.DataFrame(phone_data)7.1 品牌價(jià)格對(duì)比箱線圖
plt.figure(figsize=(10, 6))
df.boxplot(column='price', by='brand',
patch_artist=True,
boxprops=dict(facecolor='#4C72B0', color='black'),
medianprops=dict(color='white'))
plt.title('各品牌手機(jī)價(jià)格分布')
plt.suptitle('') # 去除自動(dòng)生成的標(biāo)題
plt.xlabel('品牌')
plt.ylabel('價(jià)格(元)')
plt.grid(True, linestyle='--', alpha=0.6)
plt.show()7.2 價(jià)格與評(píng)分散點(diǎn)圖
plt.figure(figsize=(10, 6))
brands = df['brand'].unique()
colors = {'Apple': '#4C72B0', 'Samsung': '#55A868', 'Huawei': '#C44E52'}
for brand in brands:
subset = df[df['brand'] == brand]
plt.scatter(subset['price'], subset['rating'],
s=100, label=brand, color=colors[brand])
plt.title('手機(jī)價(jià)格與評(píng)分關(guān)系')
plt.xlabel('價(jià)格(元)')
plt.ylabel('評(píng)分')
plt.legend()
plt.grid(True)
plt.show()常見問題Q&A
Q1:被網(wǎng)站封IP怎么辦?
A:立即啟用備用代理池,建議使用住宅代理(如站大爺IP代理),配合每請(qǐng)求更換IP策略??梢栽趓equests請(qǐng)求中添加代理參數(shù):
proxies = {
'http': 'http://your-proxy-ip:port',
'https': 'https://your-proxy-ip:port'
}
response = requests.get(url, headers=headers, proxies=proxies)Q2:中文顯示亂碼如何解決?
A:在代碼開頭添加以下配置:
plt.rcParams['font.sans-serif'] = ['SimHei'] # Windows系統(tǒng) plt.rcParams['axes.unicode_minus'] = False # 解決負(fù)號(hào)顯示問題 # 或使用Mac/Linux的字體 # plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
Q3:如何保存透明背景的圖表?
A:使用savefig的transparent參數(shù):
plt.savefig('transparent.png', dpi=300, transparent=True)Q4:圖表中的文字重疊怎么辦?
A:可以嘗試以下方法:
- 旋轉(zhuǎn)x軸標(biāo)簽:
plt.xticks(rotation=45) - 調(diào)整圖表大?。?code>plt.figure(figsize=(12, 6))
- 使用
tight_layout()自動(dòng)調(diào)整 - 手動(dòng)調(diào)整子圖間距:
plt.subplots_adjust(wspace=0.4, hspace=0.6)
Q5:如何實(shí)現(xiàn)動(dòng)態(tài)圖表?
A:可以使用matplotlib.animation模塊創(chuàng)建動(dòng)態(tài)圖表,或?qū)С鰹镠TML使用Plotly等庫實(shí)現(xiàn)交互式可視化。
結(jié)語:數(shù)據(jù)可視化的價(jià)值
通過本文的實(shí)戰(zhàn),你應(yīng)該已經(jīng)掌握了從數(shù)據(jù)爬取到專業(yè)可視化的完整流程。記住,好的可視化不是追求花哨的效果,而是準(zhǔn)確、清晰地傳達(dá)數(shù)據(jù)背后的信息。下次當(dāng)你面對(duì)一堆CSV數(shù)據(jù)時(shí),不妨先用Matplotlib畫幾張圖,往往能發(fā)現(xiàn)意想不到的洞察。
數(shù)據(jù)可視化就像給數(shù)據(jù)講故事,而Matplotlib就是你手中的畫筆?,F(xiàn)在,是時(shí)候用你爬取的數(shù)據(jù),創(chuàng)作屬于自己的數(shù)據(jù)故事了!
以上就是Python使用Matplotlib將爬取的CSV數(shù)據(jù)變成直觀圖表的詳細(xì)內(nèi)容,更多關(guān)于Python Matplotlib將CSV數(shù)據(jù)變成圖表的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python導(dǎo)入Excel表格數(shù)據(jù)并以字典dict格式保存的操作方法
本文介紹基于Python語言,將一個(gè)Excel表格文件中的數(shù)據(jù)導(dǎo)入到Python中,并將其通過字典格式來存儲(chǔ)的方法,感興趣的朋友一起看看吧2023-01-01
python實(shí)現(xiàn)隨機(jī)梯度下降法
這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)隨機(jī)梯度下降法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-08-08
OpenCV圖像梯度處理與邊緣檢測的實(shí)戰(zhàn)指南
本文主要介紹了OpenCV圖像梯度處理與邊緣檢測的實(shí)戰(zhàn)指南,包括自定義卷積核、Sobel、Laplacian和Canny算法,文中通過示例代碼介紹的非常詳細(xì),感興趣的可以了解一下2025-07-07
一文教你用Python中progress庫實(shí)現(xiàn)進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了如何通過Python中的progress庫實(shí)現(xiàn)進(jìn)度條的繪制,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03
Python使用Appium實(shí)現(xiàn)自動(dòng)化操作手機(jī)入門教學(xué)
Appium作為一個(gè)開源的移動(dòng)應(yīng)用自動(dòng)化測試框架,支持多種編程語言,包括Python、Java、Ruby等,本文將詳細(xì)介紹如何使用Python和Appium來操作手機(jī),需要的可以了解下2025-10-10
python系統(tǒng)指定文件的查找只輸出目錄下所有文件及文件夾
這篇文章主要介紹了python系統(tǒng)指定文件的查找只輸出目錄下所有文件及文件夾,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
使用Python創(chuàng)建多功能文件管理器的代碼示例
在本文中,我們將探索一個(gè)使用Python的wxPython庫開發(fā)的文件管理器應(yīng)用程序,這個(gè)應(yīng)用程序不僅能夠?yàn)g覽和選擇文件,還支持文件預(yù)覽、壓縮、圖片轉(zhuǎn)換以及生成PPT演示文稿的功能,需要的朋友可以參考下2024-08-08
django ajax發(fā)送post請(qǐng)求的兩種方法
這篇文章主要介紹了django ajax發(fā)送post請(qǐng)求的兩種方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01

