一周学会Pandas2之Python数据处理与分析-Pandas2数据绘图与可视化
锋哥原创的Pandas2 Python数据处理与分析 视频教程:
2025版 Pandas2 Python数据处理与分析 视频教程(无废话版) 玩命更新中~_哔哩哔哩_bilibili
Pandas 集成了 Matplotlib,提供了简单高效的绘图接口,使数据可视化变得直观便捷。本指南将详细介绍 Pandas 绘图的核心知识和方法,涵盖各种图表类型和高级技巧。
一、绘图基础与设置
1.1 基础绘图方法
Pandas 的 plot()
方法是绘图的核心入口点:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 引入支持中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 创建示例数据
np.random.seed(42)
df = pd.DataFrame({'A': np.random.randn(100).cumsum(),'B': np.random.randn(100).cumsum(),'C': np.random.randn(100).cumsum()
}, index=pd.date_range('2023-01-01', periods=100))
# 基本绘图
df.plot(figsize=(10, 6))
plt.title('基本折线图')
plt.ylabel('数值')
plt.xlabel('日期')
plt.grid(True)
plt.show()
1.2 绘图参数详解
常用绘图参数:
df.plot(kind='line', # 图表类型figsize=(12, 8), # 图表尺寸title='图表标题', # 标题grid=True, # 显示网格legend=True, # 显示图例colormap='viridis', # 颜色映射alpha=0.8, # 透明度style=['-', '--', ':'], # 线条样式logy=True, # Y轴对数刻度secondary_y=['B'] # 双Y轴
)
二、图表类型详解
2.1 折线图 (Line Plot)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 引入支持中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 创建示例数据
np.random.seed(42)
df = pd.DataFrame({'A': np.random.randn(100).cumsum(),'B': np.random.randn(100).cumsum(),'C': np.random.randn(100).cumsum()
}, index=pd.date_range('2023-01-01', periods=100))
# 基础折线图
df.plot(kind='line', figsize=(10, 6))
# 多线图定制
ax = df.plot(style={'A': 'g--', # 绿色虚线'B': 'ro-', # 红色圆点实线'C': 'b:' # 蓝色点线},linewidth=2,title='定制折线图'
)
ax.set_ylabel('数值')
ax.set_xlabel('日期')
plt.grid(True, linestyle='--', alpha=0.7)
plt.show()
2.2 柱状图 (Bar Plot)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 引入支持中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 创建示例数据
bar_data = pd.DataFrame({'类别': ['苹果', '香蕉', '橙子', '葡萄', '西瓜'],'销量': [120, 85, 110, 65, 95],'价格': [8.5, 6.0, 7.2, 12.8, 4.5]
})
# 垂直柱状图
bar_data.plot(kind='bar', x='类别', y='销量',color='skyblue', figsize=(10, 6),title='水果销量柱状图')
plt.ylabel('销量')
plt.show()
# 水平柱状图
bar_data.plot(kind='barh', x='类别', y='价格',color='salmon', figsize=(10, 6),title='水果价格水平柱状图')
plt.xlabel('价格(元/公斤)')
plt.show()
2.3 堆叠柱状图 (Stacked Bar Plot)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 引入支持中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 创建示例数据
sales_data = pd.DataFrame({'季度': ['Q1', 'Q2', 'Q3', 'Q4'],'线上': [120, 150, 180, 200],'线下': [80, 95, 110, 125],'批发': [200, 220, 250, 280]
})
# 堆叠柱状图
ax = sales_data.plot(kind='bar',stacked=True,x='季度',figsize=(10, 6),title='季度销售渠道分布',colormap='Set2'
)
# 添加数据标签
for p in ax.patches:width, height = p.get_width(), p.get_height()x, y = p.get_xy()if height > 0:ax.annotate(f'{height:.0f}', (x + width / 2, y + height / 2),ha='center', va='center')
plt.ylabel('销售额(万元)')
plt.show()
2.4 直方图 (Histogram)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 引入支持中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 创建示例数据
np.random.seed(42)
normal_data = pd.Series(np.random.normal(0, 1, 1000))
exp_data = pd.Series(np.random.exponential(1, 1000))
# 直方图
fig, axes = plt.subplots(1, 2, figsize=(14, 6))
normal_data.plot(kind='hist', bins=30, ax=axes[0],color='skyblue', edgecolor='black',title='正态分布直方图')
axes[0].set_xlabel('值')
exp_data.plot(kind='hist', bins=30, ax=axes[1],color='salmon', edgecolor='black',title='指数分布直方图')
axes[1].set_xlabel('值')
plt.tight_layout()
plt.show()
2.5 密度图 (Density Plot)
需要新安装scipy库
pip install scipy -i https://mirrors.aliyun.com/pypi/simple
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 引入支持中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 创建示例数据
np.random.seed(42)
normal_data = pd.Series(np.random.normal(0, 1, 1000))
exp_data = pd.Series(np.random.exponential(1, 1000))
# 密度图
fig, ax = plt.subplots(figsize=(10, 6))
normal_data.plot(kind='kde', ax=ax, label='正态分布')
exp_data.plot(kind='kde', ax=ax, label='指数分布')
ax.set_title('分布密度比较')
ax.set_xlabel('值')
ax.legend()
ax.grid(True, linestyle='--', alpha=0.7)
plt.show()
2.6 箱线图 (Box Plot)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 引入支持中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 创建示例数据
np.random.seed(42)
box_data = pd.DataFrame({'A': np.random.normal(0, 1, 100),'B': np.random.normal(2, 1.5, 100),'C': np.random.normal(-1, 0.8, 100),'D': np.random.exponential(1, 100)
})
# 箱线图
ax = box_data.plot(kind='box', figsize=(10, 6),title='多变量箱线图比较',vert=False, # 水平箱线图patch_artist=True, # 填充颜色boxprops=dict(facecolor='lightblue'),medianprops=dict(color='red', linewidth=2),whiskerprops=dict(color='black'),capprops=dict(color='black'),flierprops=dict(marker='o', markersize=5, markerfacecolor='gray'))
ax.set_xlabel('值')
plt.grid(True, axis='x', linestyle='--', alpha=0.7)
plt.show()
2.7 散点图 (Scatter Plot)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 引入支持中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 创建示例数据
np.random.seed(42)
data = {'销售额': np.random.normal(50000, 15000, 100),'广告投入': np.random.normal(10000, 3000, 100),'客户满意度': np.random.randint(1, 10, 100),'产品类别': np.random.choice(['A', 'B', 'C'], 100)
}
df = pd.DataFrame(data)
# 基础散点图
df.plot.scatter(x='广告投入', y='销售额',title='广告投入 vs 销售额',figsize=(10, 6),grid=True)
plt.tight_layout()
plt.savefig('basic_scatter.png', dpi=120)
plt.show()
2.8 饼图 (Pie Chart)
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 引入支持中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 创建示例数据
pie_data = pd.Series({'亚洲': 45,'欧洲': 25,'北美': 15,'南美': 8,'非洲': 5,'大洋洲': 2
}, name='市场份额')
# 饼图
ax = pie_data.plot(kind='pie', figsize=(10, 8), autopct='%1.1f%%',startangle=90, shadow=True, explode=[0.1, 0, 0, 0, 0, 0],colors=['#ff9999', '#66b3ff', '#99ff99', '#ffcc99', '#c2c2f0', '#ffb3e6'],title='全球市场份额分布')
ax.set_ylabel('') # 隐藏Y轴标签
plt.axis('equal') # 保证饼图是圆形
plt.show()
三、时间序列可视化
基础时间序列图
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from pylab import mpl
# 引入支持中文字体
mpl.rcParams["font.sans-serif"] = ["SimHei"]
mpl.rcParams["axes.unicode_minus"] = False
# 创建时间序列数据
np.random.seed(42)
dates = pd.date_range('2023-01-01', periods=365)
ts_data = pd.DataFrame({'销量': 100 + np.sin(np.linspace(0, 10 * np.pi, 365)) * 50 +np.random.normal(0, 10, 365),'温度': 15 + 20 * np.sin(np.linspace(0, 2 * np.pi, 365)) +np.random.normal(0, 3, 365)
}, index=dates)
# 时间序列图
ax = ts_data['销量'].plot(figsize=(12, 6), color='blue', label='销量')
ax.set_ylabel('销量')
# 双Y轴
ax2 = ax.twinx()
ts_data['温度'].plot(ax=ax2, color='red', linestyle='--', label='温度')
ax2.set_ylabel('温度(℃)')
# 添加标题和图例
plt.title('销量与温度变化趋势')
lines, labels = ax.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax.legend(lines + lines2, labels + labels2, loc='upper left')
# 添加网格
ax.grid(True, linestyle='--', alpha=0.7)
plt.show()