欢迎关注微信公众号
# 安装 pip install matplotlib numpy pandas # Jupyter 中显示图形 import matplotlib.pyplot as plt %matplotlib inline # Jupyter Notebook %matplotlib widget # JupyterLab(交互式) # 脚本中显示 plt.show() # 显示图形窗口
pyplot
(MATLAB风格,快速绘图)和
面向对象
(显式控制Figure/Axes,推荐用于复杂图形)。
import matplotlib.pyplot as plt import numpy as np # 准备数据 x = np.linspace(0, 10, 100) y1 = np.sin(x) y2 = np.cos(x) # ========== pyplot 风格 ========== plt.plot(x, y1, label='sin(x)', color='blue', linestyle='-') plt.plot(x, y2, label='cos(x)', color='red', linestyle='--') plt.xlabel('X轴') plt.ylabel('Y轴') plt.title('正弦与余弦函数') plt.legend() # 显示图例 plt.grid(True) # 显示网格 plt.show() # ========== 面向对象风格(推荐) ========== fig, ax = plt.subplots(figsize=(8, 5)) ax.plot(x, y1, label='sin(x)', color='blue') ax.plot(x, y2, label='cos(x)', color='red') ax.set_xlabel('X轴') ax.set_ylabel('Y轴') ax.set_title('正弦与余弦函数') ax.legend() ax.grid(True) plt.show()
import matplotlib.pyplot as plt import numpy as np np.random.seed(42) x = np.random.rand(50) y = np.random.rand(50) colors = np.random.rand(50) sizes = 1000 * np.random.rand(50) fig, ax = plt.subplots() ax.scatter(x, y, c=colors, s=sizes, alpha=0.5, cmap='viridis') ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_title('散点图') plt.show()
categories = ['A', 'B', 'C', 'D'] values = [23, 45, 56, 78] fig, ax = plt.subplots() bars = ax.bar(categories, values, color=['red', 'green', 'blue', 'orange'], edgecolor='black') # 在柱子上添加数值标签 for bar in bars: height = bar.get_height() ax.annotate(f'{height}', xy=(bar.get_x() + bar.get_width() / 2, height), xytext=(0, 3), textcoords="offset points", ha='center', va='bottom') ax.set_ylabel('数值') ax.set_title('柱状图') plt.show()
import matplotlib.pyplot as plt import numpy as np data = np.random.randn(1000) fig, ax = plt.subplots() ax.hist(data, bins=30, color='skyblue', edgecolor='black', alpha=0.7) ax.set_xlabel('数值') ax.set_ylabel('频数') ax.set_title('直方图') # 添加密度曲线 from scipy import stats xmin, xmax = ax.get_xlim() x = np.linspace(xmin, xmax, 100) p = stats.norm.pdf(x, 0, 1) ax.plot(x, p * 1000 * 30 / (2*xmax), 'r-') plt.show()
sizes = [30, 25, 20, 15, 10] labels = ['A', 'B', 'C', 'D', 'E'] explode = (0.1, 0, 0, 0, 0) fig, ax = plt.subplots() ax.pie(sizes, explode=explode, labels=labels, autopct='%1.1f%%', startangle=90, shadow=True) ax.set_title('饼图') plt.show() # 箱线图 boxplot data = [np.random.normal(0, std, 100) for std in range(1, 5)] fig, ax = plt.subplots() ax.boxplot(data) ax.set_title('箱线图') plt.show()
import matplotlib.pyplot as plt import numpy as np # ========== 方式1:subplots 创建多子图 ========== fig, axes = plt.subplots(2, 2, figsize=(10, 8)) # 2行2列 x = np.linspace(0, 10, 100) axes[0, 0].plot(x, np.sin(x)) axes[0, 0].set_title('sin(x)') axes[0, 1].plot(x, np.cos(x)) axes[0, 1].set_title('cos(x)') axes[1, 0].plot(x, np.tan(x)) axes[1, 0].set_title('tan(x)') axes[1, 1].plot(x, np.exp(-x)) axes[1, 1].set_title('exp(-x)') fig.tight_layout() # 自动调整子图间距 plt.show() # ========== 方式2:subplot 逐个添加 ========== plt.figure(figsize=(10, 4)) plt.subplot(1, 2, 1) # 1行2列,第1个 plt.plot(x, np.sin(x)) plt.subplot(1, 2, 2) # 1行2列,第2个 plt.plot(x, np.cos(x)) plt.show()
import matplotlib.pyplot as plt import matplotlib as mpl # 全局样式设置 plt.style.use('seaborn-v0_8-whitegrid') # 内置样式 mpl.rcParams['font.family'] = 'SimHei' # 中文字体 mpl.rcParams['axes.unicode_minus'] = False # 负号正常显示 # 颜色与标记 fig, ax = plt.subplots() ax.plot(x, y1, color='#FF6B6B', linewidth=2, marker='o', markersize=6, markerfacecolor='white') # 自定义刻度 ax.set_xticks([0, np.pi, 2*np.pi]) ax.set_xticklabels(['0', r'$\pi$', r'$2\pi$']) # 添加注释 ax.annotate('最大值', xy=(np.pi/2, 1), xytext=(np.pi/2 + 1, 0.5), arrowprops=dict(arrowstyle='->', color='red')) # 设置坐标轴范围 ax.set_xlim(0, 2*np.pi) ax.set_ylim(-1.5, 1.5) # 保存图片 fig.savefig('plot.png', dpi=300, bbox_inches='tight') plt.show()
Seaborn 是基于 Matplotlib 的高级统计可视化库,内置美观的默认样式,一行代码即可生成复杂统计图。
import seaborn as sns import matplotlib.pyplot as plt import pandas as pd import numpy as np # 设置主题 sns.set_theme(style='whitegrid') # darkgrid, white, ticks # 示例数据 df = pd.DataFrame({ 'x': np.random.randn(100), 'y': np.random.randn(100), 'category': np.random.choice(['A', 'B', 'C'], 100), 'size': np.random.rand(100) }) # 快速统计图 sns.scatterplot(data=df, x='x', y='y', hue='category', size='size') plt.show() # 箱线图 sns.boxplot(data=df, x='category', y='y', palette='Set2') plt.show() # 热力图 corr = df[['x', 'y', 'size']].corr() sns.heatmap(corr, annot=True, cmap='coolwarm', fmt='.2f') plt.show()
# 核密度估计图 sns.kdeplot(data=df, x='x', hue='category') # 直方图+密度 sns.histplot(data=df, x='x', kde=True) # 小提琴图 sns.violinplot(data=df, x='category', y='y') # 配对图(多变量关系) sns.pairplot(df, hue='category')
# 带回归线的散点图 sns.regplot(data=df, x='x', y='y') # 分面网格 g = sns.FacetGrid(df, col='category') g.map(sns.histplot, 'x') # 联合分布图 sns.jointplot(data=df, x='x', y='y', kind='scatter') # kind: scatter, kde, hex, reg, resid # 条形图(带误差线) sns.barplot(data=df, x='category', y='y')
data
+ 列名参数,自动处理数据框;
hue
参数按类别分组着色,是Seaborn最强大的特性。
Pandas DataFrame/Series 内置了
.plot()
方法,底层调用 Matplotlib,实现「数据→图形」的一步直达。
import pandas as pd import numpy as np # 创建时间序列数据 dates = pd.date_range('2024-01-01', periods=100) df = pd.DataFrame({ 'A': np.cumsum(np.random.randn(100)), 'B': np.cumsum(np.random.randn(100)), 'C': np.random.rand(100) * 100 }, index=dates) # 1. DataFrame.plot() — 折线图(默认) df.plot(figsize=(10, 5), title='时间序列') # 2. 指定图表类型 df.plot(kind='bar') # 柱状图 df.plot(kind='hist') # 直方图 df.plot(kind='scatter', x='A', y='B') # 散点图 df.plot(kind='box') # 箱线图 df.plot(kind='pie', y='C') # 饼图 # 3. 子图布局 df.plot(subplots=True, layout=(3, 1), figsize=(10, 10)) # 4. Series 直接绘图 df['A'].plot(kind='area', alpha=0.5)
import matplotlib.pyplot as plt import seaborn as sns import pandas as pd import numpy as np # 准备数据 np.random.seed(42) df = pd.DataFrame({ 'month': pd.date_range('2024-01', periods=12, freq='M'), 'sales': np.random.randint(100, 500, 12), 'profit': np.random.randint(20, 100, 12), 'region': ['North', 'South', 'East', 'West'] * 3 }) # 组合图:折线+柱状 fig, ax1 = plt.subplots(figsize=(10, 5)) ax1.bar(df['month'].dt.month, df['sales'], color='skyblue', label='Sales') ax1.set_xlabel('Month') ax1.set_ylabel('Sales', color='blue') ax2 = ax1.twinx() # 共享X轴 ax2.plot(df['month'].dt.month, df['profit'], color='red', marker='o', label='Profit') ax2.set_ylabel('Profit', color='red') fig.legend(loc='upper left') plt.title('月度销售与利润') plt.show()
Figure
(画布)→
Axes
(子图)→
Axis
(坐标轴),面向对象风格更灵活
plot()
、散点图
scatter()
、柱状图
bar()
、直方图
hist()
、饼图
pie()
、箱线图
boxplot()
plt.subplots()
创建网格子图,
tight_layout()
自动调整间距
style.use()
、颜色/标记/注释、中文字体设置、
savefig()
保存
hue
分组、
pairplot
配对、
heatmap
热力图、
FacetGrid
分面
kind
切换图表类型,
subplots=True
多子图
可视化是数据科学最后也是最关键的一步——让数据开口说话。