Python使用Matplotlib将爬取的CSV数据变成直观图表

作者:

文章目录
  • 当你在电商网站爬取了10万条商品价格数据,或是从气象站抓取了3年的温度记录,面对密密麻麻的CSV表格时,是否感到无从下手?这时候,数据可视化就像给数据装上了一副"透 视镜",能让你一眼看穿数据背后的规律。 本文将带你完成一个完整的数据可视化实战:从爬取某招聘网站的职位信息,到用Matplotlib生成专业图表。不需要数学博士背景,只需跟着步骤操作,你就能做出让同事惊叹的可视化报告。
  • 爬取的原始数据往往包含脏数据,比如薪资字段可能包含"15-20K/月"这样的文本。我们需要将其转换为数值: def clean_salary(salary_str): try: # 提取数字部分,例如”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’]) # 删除薪资为空的记录 对于城市字段,我们可能需要统计每个城市的职位数量: city_counts = data[‘city’].value_counts().head(10) # 取前10个城市
  • 假设我们爬取了某电商平台的手机价格数据: # 模拟数据 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)
  • Q1:被网站封IP怎么办? A:立即启用备用代理池,建议使用住宅代理(如站大爷IP代理),配合每请求更换IP策略。可以在requests请求中添加代理参数: 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系统 plt.rcParams[‘axes.unicode_minus’] = False # 解决负号显示问题 # 或使用Mac/Linux的字体 # plt.rcParams[‘font.sans-serif’] = [‘Arial Unicode MS’] Q3:如何保存透明背景的图表? A:使用savefig的transparent参数: plt.savefig(‘transparent.png’, dpi=300, transparent=True) Q4:图表中的文字重叠怎么办? A:可以尝试以下方法: 旋转x轴标签:plt.xticks(rotation=45) 调整图表大小:plt.figure(figsize=(12, 6)) 使用tight_layout()自动调整 手动调整子图间距:plt.subplots_adjust(wspace=0.4, hspace=0.6) Q5:如何实现动态图表? A:可以使用matplotlib.animation模块创建动态图表,或导出为HTML使用Plotly等库实现交互式可视化。
  • 通过本文的实战,你应该已经掌握了从数据爬取到专业可视化的完整流程。记住,好的可视化不是追求花哨的效果,而是准确、清晰地传达数据背后的信息。下次当你面对一堆CSV数据时,不妨先用Matplotlib画几张图,往往能发现意想不到的洞察。 数据可视化就像给数据讲故事,而Matplotlib就是你手中的画笔。现在,是时候用你爬取的数据,创作属于自己的数据故事了! 以上就是Python使用Matplotlib将爬取的CSV数据变成直观图表的详细内容,更多关于Python Matplotlib将CSV数据变成图表的资料请关注风君子博客其它相关文章! 您可能感兴趣的文章: Python使用Matplotlib绘制专业柱状图的完整指南 Python安装Matplotlib库的五种方法小结 使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形) Python中OpenCV与Matplotlib的图像操作入门指南 使用Python Matplotlib处理地理数据可视化
  • 目录
    • 引言:为什么需要数据可视化?
    • 一、准备阶段:环境搭建与数据获取
      • 1.1 基础环境配置
      • 1.2 爬取示例数据
    • 二、数据清洗:让数据"干净"起来
      • 三、基础图表制作:柱状图与折线图
        • 3.1 城市职位分布柱状图
        • 3.2 薪资趋势折线图
      • 四、进阶图表:散点图与饼图
        • 4.1 薪资与经验相关性散点图
        • 4.2 薪资范围饼图
      • 五、多图表组合:子图与仪表盘
        • 5.1 创建包含多个图表的仪表盘
      • 六、样式优化:让图表更专业
        • 6.1 全局样式设置
        • 6.2 颜色搭配技巧
      • 七、实际应用案例:电商价格监控
        • 7.1 品牌价格对比箱线图
        • 7.2 价格与评分散点图
      • 常见问题Q&A
        • 结语:数据可视化的价值

          当你在电商网站爬取了10万条商品价格数据,或是从气象站抓取了3年的温度记录,面对密密麻麻的CSV表格时,是否感到无从下手?这时候,数据可视化就像给数据装上了一副"透 视镜",能让你一眼看穿数据背后的规律。

          本文将带你完成一个完整的数据可视化实战:从爬取某招聘网站的职位信息,到用Matplotlib生成专业图表。不需要数学博士背景,只需跟着步骤操作,你就能做出让同事惊叹的可视化报告。

          首先确保你的Python环境已安装必要的库:

          pip install matplotlib pandas requests beautifulsoup4

          这四个库的分工很明确:

          • requests:负责发送HTTP请求获取网页
          • BeautifulSoup4:解析HTML提取数据
          • pandas:处理CSV数据
          • matplotlib:绘制可视化图表

          以某招聘网站为例,我们爬取Python开发岗位的薪资和城市分布数据:

          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')
                  
                  # 假设每个职位在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()

          提示:实际爬取时需遵守网站的robots协议,建议添加延迟(time.sleep(2))避免被封。

          爬取的原始数据往往包含脏数据,比如薪资字段可能包含"15-20K/月"这样的文本。我们需要将其转换为数值:

          def clean_salary(salary_str):
              try:
                  # 提取数字部分,例如"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'])  # 删除薪资为空的记录

          对于城市字段,我们可能需要统计每个城市的职位数量:

          city_counts = data['city'].value_counts().head(10)  # 取前10个城市

          柱状图最适合展示分类数据的对比:

          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('职位数量', fontsize=12)
          plt.xticks(rotation=45)  # 旋转x轴标签
          plt.grid(axis='y', linestyle='--', alpha=0.7)
           
          # 在柱子上方显示数值
          for i, v in enumerate(city_counts):
              plt.text(i, v + 50, str(v), ha='center')
           
          plt.tight_layout()  # 自动调整布局
          plt.savefig('city_distribution.png', dpi=300)
          plt.show()

          效果说明

          • 蓝色柱子高度代表职位数量
          • 每个柱子上方显示具体数值
          • 网格线辅助读数
          • 图片保存为300dpi高清图

          假设我们按经验要求分组统计平均薪资:

          # 假设数据中有'experience'字段
          exp_salary = data.groupby('experience')['salary'].mean()
           
          plt.figure(figsize=(10, 5))
          exp_salary.plot(kind='line', marker='o', color='#DD8452')
           
          plt.title('不同经验要求的平均薪资', fontsize=14)
          plt.xlabel('经验要求', fontsize=11)
          plt.ylabel('平均薪资(K)', fontsize=11)
          plt.grid(True, linestyle=':', alpha=0.6)
           
          # 标记数据点
          for x, y in zip(exp_salary.index, exp_salary):
              plt.text(x, y, f'{y:.1f}K', ha='center', va='bottom')
           
          plt.show()

          关键点

          • 橙色折线连接各数据点
          • 每个数据点上方显示具体数值
          • 虚线网格增强可读性

          探索薪资与工作经验是否相关:

          # 假设我们随机生成一些经验年限数据
          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控制点大小
           
          plt.title('工作经验与薪资关系', fontsize=15)
          plt.xlabel('工作经验(年)', 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()

          解读

          • 绿色散点表示各个数据点
          • 红色虚线为线性趋势线
          • 透明度(alpha)设置避免点重叠

          展示不同薪资区间的职位占比:

          # 创建薪资区间
          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控制起始角度
          • 自定义颜色让图表更美观

          fig, axes = plt.subplots(2, 2, figsize=(14, 10))
          fig.suptitle('Python岗位数据分析仪表盘', 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:经验-薪资散点
          axes[0,1].scatter(data['experience_years'], data['salary'], 
                            alpha=0.5, color='#55A868')
          axes[0,1].set_title('经验与薪资关系')
           
          # 子图3:薪资范围饼图
          axes[1,0].pie(range_counts, labels=None, autopct='%1.1f%%',
                        colors=['#C44E52', '#CCB974', '#64776D', '#798E87'])
          axes[1,0].set_title('薪资分布')
           
          # 子图4:经验要求折线图
          exp_salary.plot(kind='line', marker='o', ax=axes[1,1], color='#DD8452')
          axes[1,1].set_title('经验要求与平均薪资')
           
          plt.tight_layout()
          plt.subplots_adjust(top=0.92)  # 调整标题位置
          plt.savefig('dashboard.png', dpi=300)
          plt.show()

          优势

          • 单张图片展示多个维度
          • 适合放入分析报告
          • 保持统一的风格

          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
          })

          推荐使用以下配色方案:

          • 分类数据:['#4C72B0', '#55A868', '#C44E52', '#CCB974']
          • 连续数据:['#313695', '#4575b4', '#74add1', '#abd9e9']

          可以使用在线工具Coolors生成配色方案。

          假设我们爬取了某电商平台的手机价格数据:

          # 模拟数据
          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)

          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('各品牌手机价格分布')
          plt.suptitle('')  # 去除自动生成的标题
          plt.xlabel('品牌')
          plt.ylabel('价格(元)')
          plt.grid(True, linestyle='--', alpha=0.6)
          plt.show()

          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('手机价格与评分关系')
          plt.xlabel('价格(元)')
          plt.ylabel('评分')
          plt.legend()
          plt.grid(True)
          plt.show()

          Q1:被网站封IP怎么办?

          A:立即启用备用代理池,建议使用住宅代理(如站大爷IP代理),配合每请求更换IP策略。可以在requests请求中添加代理参数:

          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系统
          plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
          # 或使用Mac/Linux的字体
          # plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']

          Q3:如何保存透明背景的图表?

          A:使用savefigtransparent参数:

          plt.savefig('transparent.png', dpi=300, transparent=True)

          Q4:图表中的文字重叠怎么办?

          A:可以尝试以下方法:

          • 旋转x轴标签:plt.xticks(rotation=45)
          • 调整图表大小:plt.figure(figsize=(12, 6))
          • 使用tight_layout()自动调整
          • 手动调整子图间距:plt.subplots_adjust(wspace=0.4, hspace=0.6)

          Q5:如何实现动态图表?

          A:可以使用matplotlib.animation模块创建动态图表,或导出为HTML使用Plotly等库实现交互式可视化。

          通过本文的实战,你应该已经掌握了从数据爬取到专业可视化的完整流程。记住,好的可视化不是追求花哨的效果,而是准确、清晰地传达数据背后的信息。下次当你面对一堆CSV数据时,不妨先用Matplotlib画几张图,往往能发现意想不到的洞察。

          数据可视化就像给数据讲故事,而Matplotlib就是你手中的画笔。现在,是时候用你爬取的数据,创作属于自己的数据故事了!

          以上就是Python使用Matplotlib将爬取的CSV数据变成直观图表的详细内容,更多关于Python Matplotlib将CSV数据变成图表的资料请关注风君子博客其它相关文章!

          您可能感兴趣的文章:

          • Python使用Matplotlib绘制专业柱状图的完整指南
          • Python安装Matplotlib库的五种方法小结
          • 使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)
          • Python中OpenCV与Matplotlib的图像操作入门指南
          • 使用Python Matplotlib处理地理数据可视化

          站内搜索