1.引言
在数据分析应用场景,当我们想要知道数据的分布,或者结果展示,一堆堆数字是不那么优美的!图形化展示多好!这个时候,可以考虑选择matplotlib库,matplotlib库是python最著名的2D绘图库,应用场景非常丰富。比如:
- 数据探索与可视化呈现
- 报表图表制作
- 交互式数据分析
- 机器学习深度学习结果展示
等等。在绘图应用场景,matplotlib库提供了相关核心组件。
- 画布(顶层容器):Figure
- 子图(坐标系区域):Axes
- 标尺(坐标轴):Axis
- 绘画元素(所有可见元素):Artist
今天,我们通过一篇文章完成matplotlib库的全面入门。开始吧!
2.案例
2.1.环境准备
使用matplotlib库,需要安装
pip install matplotlib
# 标准导入方式
import matplotlib.pyplot as plt
如上环境准备好,即可以愉快的使用了。
2.2.直观体验
在进一步学习使用前,先来一个案例直观感受一下。案例场景画一幅正弦曲线图。
准备数据:
import numpy as np
# 生成数字序列数据,以及求取相应的正弦值
x = np.linspace(0, 2*np.pi, 10)
y = np.sin(x)
print(f"x轴序列值:{x}")
print(f"y轴序列值:{y}")
针对上述序列值:x,y来绘制曲线
import numpy as np
# 生成数字序列数据,以及求取相应的正弦值
x = np.linspace(0, 2*np.pi, 10)
y = np.sin(x)
print(f"x轴序列值:{x}")
print(f"y轴序列值:{y}")
import matplotlib.pyplot as plt
# 显示中文设置(解决中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 微软雅黑
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示
# 创建图形
plt.figure(figsize=(6,3)) # 设置画布尺寸
# 绘制曲线
plt.plot(x, y,
color='red',
linestyle='--',
linewidth=2,
marker='o',
markersize=5,
label='正弦曲线')
# 添加装饰
plt.title("基本正弦曲线图") # 标题
plt.xlabel("X轴") # X轴标签
plt.ylabel("Y轴") # Y轴标签
plt.grid(True) # 显示网格
plt.legend() # 显示图例
# 显示图形
plt.show()
2.3.基础图表类型
在实际应用中,基于不同的需求场景目标,需要不同类型的图表来做展示,如何选择?
- 趋势分析:折线图
- 相关性分析:散点图
- 分类比较:柱状图
- 比例分析:饼图
以上是常用场景以及相应的图表类型,我们来各看一个案例。
2.3.1.折线图(plot)
import numpy as np
import matplotlib.pyplot as plt
# 显示中文设置(解决中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 微软雅黑
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示
# 生成股票模拟数据
days = np.arange(1, 31)
price = 50 + np.cumsum(np.random.randn(30))
print(f"x轴:{days}")
print(f"y轴:{price}")
plt.figure(figsize=(10,5))
plt.plot(days, price,
color='steelblue',
marker='D',
label='每日收盘价')
plt.title("股票价格趋势分析")
plt.xlabel("交易日")
plt.ylabel("价格(人民币)")
plt.legend()
plt.show()
数据:
图表:
2.3.2.散点图(scatter)
import numpy as np
import matplotlib.pyplot as plt
# 显示中文设置(解决中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 微软雅黑
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示
# 生成身高体重数据
height = np.random.normal(170, 10, 100)
weight = 0.7*height - 50 + np.random.randn(100)*5
print(f"x轴数据:{height}")
print(f"y轴数据:{weight}")
plt.figure(figsize=(8,6))
plt.scatter(height, weight,
c='purple', # 颜色
alpha=0.6, # 透明度
edgecolors='w', # 边缘色
s=50) # 点大小
plt.title("身高体重相关性分析")
plt.xlabel("身高(cm)")
plt.ylabel("体重(kg)")
plt.grid(True)
plt.show()
数据:
图表:
2.3.3.柱状图(bar)
import numpy as np
import matplotlib.pyplot as plt
# 显示中文设置(解决中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 微软雅黑
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示
# 销售数据
products = ['手机', '笔记本', '平板', '耳机']
sales = [235, 180, 92, 156]
plt.figure(figsize=(6,3))
bars = plt.bar(products, sales,
color=['#2ecc71','#3498db','#e74c3c','#f1c40f'],
edgecolor='black')
# 添加数据标签
for bar in bars:
height = bar.get_height()
plt.text(bar.get_x() + bar.get_width()/2., height,
f'{height}',
ha='center', va='bottom')
plt.title("季度产品销量对比")
plt.ylabel("销量(万台)")
plt.ylim(0, 250)
plt.show()
2.3.4.饼图(pie)
import numpy as np
import matplotlib.pyplot as plt
# 显示中文设置(解决中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 微软雅黑
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示
# 市场份额数据
labels = ['苹果', '三星', '华为', '其他']
sizes = [45, 25, 20, 10]
explode = (0.1, 0, 0, 0) # 突出显示第一块
plt.figure(figsize=(6,6))
plt.pie(sizes,
explode=explode,
labels=labels,
autopct='%1.1f%%',
startangle=90,
shadow=True,
colors=['#ff9999','#66b3ff','#99ff99','#ffcc99'])
plt.title("智能手机市场份额")
plt.show()
2.4.图表美化
2.4.1.样式定制
我们可以根据需要,对图表进行相应样式定制。比如
# 使用预置样式
plt.style.use('ggplot')
# 自定义样式
plt.rcParams.update({
'font.size': 12,
'axes.titlesize': 16,
'axes.labelsize': 14,
'xtick.labelsize': 10,
'ytick.labelsize': 10,
'figure.figsize': (10,6)
})
2.4.2.多子图布局
在一块画布上展示多个子类型图表
import numpy as np
import matplotlib.pyplot as plt
# 显示中文设置(解决中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 微软雅黑
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示
fig, axs = plt.subplots(2, 2, figsize=(13,8))
# 子图1:折线图
x = np.linspace(0, 2*np.pi, 10)
y = np.sin(x)
axs[0,0].plot(x, np.sin(x), 'r--')
axs[0,0].set_title('正弦曲线')
# 子图2:散点图
axs[0,1].scatter(np.random.rand(50), np.random.rand(50))
axs[0,1].set_title('随机散点')
# 子图3:柱状图
axs[1,0].bar(['A','B','C'], [3,7,5])
axs[1,0].set_title('分类比较')
# 子图4:饼图
axs[1,1].pie([30,20,50], labels=['X','Y','Z'])
axs[1,1].set_title('比例分布')
plt.tight_layout() # 自动调整间距
plt.show()
2.4.3.绘制3D图
import numpy as np
import matplotlib.pyplot as plt
# 显示中文设置(解决中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 微软雅黑
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示
fig = plt.figure(figsize=(10,7))
ax = fig.add_subplot(111, projection='3d')
# 生成数据
x = np.linspace(-5,5,100)
y = np.linspace(-5,5,100)
X,Y = np.meshgrid(x,y)
Z = np.sin(np.sqrt(X**2 + Y**2))
# 绘制曲面
surf = ax.plot_surface(X,Y,Z, cmap='viridis')
# 添加颜色条
fig.colorbar(surf, shrink=0.5, aspect=5)
ax.set_title("3D曲面图")
ax.set_xlabel("X轴")
ax.set_ylabel("Y轴")
ax.set_zlabel("Z轴")
plt.show()
2.5.实战案例
通过折线图,柱状图混合模拟之前新冠疫情发展态势,更好的做好疫情监控。
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 模拟疫情数据
dates = pd.date_range('2023-01-01', periods=30)
data = {
'日期': dates,
'新增确诊': np.random.randint(100,500,30),
'治愈人数': np.random.randint(80,400,30),
'死亡人数': np.random.randint(0,20,30)
}
df = pd.DataFrame(data)
df['累计确诊'] = df['新增确诊'].cumsum()
# 显示中文设置(解决中文乱码)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 微软雅黑
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示
plt.figure(figsize=(12,6))
# 绘制双轴曲线
ax1 = plt.gca() # 获取当前坐标系
line1 = ax1.plot(df['日期'], df['累计确诊'],
'b-', label='累计确诊')
# 创建次坐标轴
ax2 = ax1.twinx()
line2 = ax2.bar(df['日期'], df['新增确诊'],
alpha=0.3,
color='orange',
label='每日新增')
# 统一图例
lines = line1 + [line2]
labels = [l.get_label() for l in lines]
ax1.legend(lines, labels, loc='upper left')
# 设置标签
ax1.set_xlabel("日期")
ax1.set_ylabel("累计确诊人数", color='b')
ax2.set_ylabel("每日新增人数", color='orange')
plt.title("新冠疫情发展趋势")
plt.xticks(rotation=45)
plt.show()