Chapter 08 / 10

数据可视化

matplotlib 内联图表、pandas 富显示、Seaborn 统计图,让数据在 Notebook 中"说话"

内联图表基础设置

在使用 matplotlib 之前,需要先设置内联显示模式:

# 在 Notebook 顶部执行一次即可
%matplotlib inline

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

# 提高图表分辨率(Retina 屏推荐)
%config InlineBackend.figure_format = 'retina'

# 设置中文字体(防止乱码)
plt.rcParams['font.sans-serif'] = ['SimHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False

基础折线图

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 2 * np.pi, 300)
y1 = np.sin(x)
y2 = np.cos(x)

fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(x, y1, label='sin(x)', color='#f37626', linewidth=2)
ax.plot(x, y2, label='cos(x)', color='#4fc3f7', linewidth=2, linestyle='--')
ax.set_title('三角函数对比', fontsize=14)
ax.set_xlabel('x (弧度)')
ax.set_ylabel('y')
ax.legend()
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()  # 图表直接显示在单元格下方
TIP 使用 fig, ax = plt.subplots() 的面向对象 API,而不是 plt.plot() 过程式 API。在 Notebook 中同时运行多个图表时,面向对象 API 更不容易产生意外的全局状态污染。

子图(Subplots)

fig, axes = plt.subplots(2, 3, figsize=(14, 7))
fig.suptitle('多子图演示', fontsize=16)

x = np.linspace(0, 10, 100)

# 第一行:折线图、散点图、柱状图
axes[0,0].plot(x, np.sin(x)); axes[0,0].set_title('折线图')
axes[0,1].scatter(x, np.random.randn(100)); axes[0,1].set_title('散点图')
axes[0,2].bar(['A','B','C','D'], [3,7,2,5]); axes[0,2].set_title('柱状图')

# 第二行:直方图、箱线图、饼图
data = np.random.randn(500)
axes[1,0].hist(data, bins=30, color='#f37626'); axes[1,0].set_title('直方图')
axes[1,1].boxplot([np.random.randn(100) for _ in range(3)]); axes[1,1].set_title('箱线图')
axes[1,2].pie([30,25,20,25], labels=['A','B','C','D']); axes[1,2].set_title('饼图')

plt.tight_layout()
plt.show()

pandas DataFrame 富显示

pandas 的 DataFrame 在 Jupyter 中会自动渲染成格式化的 HTML 表格:

import pandas as pd

# DataFrame 直接显示为格式化表格
df = pd.DataFrame({
    '语言': ['Python', 'JavaScript', 'Java', 'Go', 'Rust'],
    '流行度': [85, 78, 65, 55, 48],
    '薪资指数': [92, 80, 75, 88, 95]
})

# 直接输入变量名即可,无需 print
df
pandas DataFrame 表格显示
pandas DataFrame 在 Jupyter 中以 HTML 表格形式渲染,比纯文本更易读

DataFrame 样式设置

# 高亮最大值
df.style.highlight_max(color='#f37626', axis=0)

# 数值条形背景
df.style.bar(subset=['流行度', '薪资指数'], color='#4fc3f7')

# 设置格式
df.style.format({'流行度': '{:.0f}%', '薪资指数': '{:.0f}K'})

Seaborn 统计图

import seaborn as sns

# 使用 Seaborn 内置数据集
tips = sns.load_dataset('tips')

fig, axes = plt.subplots(1, 3, figsize=(15, 5))

# 散点图 + 回归线
sns.regplot(data=tips, x='total_bill', y='tip', ax=axes[0])
axes[0].set_title('账单 vs 小费')

# 分组箱线图
sns.boxplot(data=tips, x='day', y='total_bill', hue='sex', ax=axes[1])
axes[1].set_title('各天账单分布')

# 热力图(相关矩阵)
corr = tips[['total_bill', 'tip', 'size']].corr()
sns.heatmap(corr, annot=True, cmap='coolwarm', ax=axes[2])
axes[2].set_title('相关矩阵')

plt.tight_layout()
plt.show()

ipywidgets 交互式控件

ipywidgets 让图表变成可交互的工具:

from ipywidgets import interact, IntSlider
import matplotlib.pyplot as plt
import numpy as np

def plot_sine(frequency=1, amplitude=1):
    x = np.linspace(0, 2 * np.pi, 300)
    y = amplitude * np.sin(frequency * x)

    plt.figure(figsize=(8, 3))
    plt.plot(x, y, color='#f37626', linewidth=2)
    plt.ylim(-3, 3)
    plt.title(f'sin({frequency}x) × {amplitude}')
    plt.grid(True, alpha=0.3)
    plt.show()

# 自动生成滑块控件
interact(plot_sine,
         frequency=IntSlider(min=1, max=10, value=1),
         amplitude=IntSlider(min=1, max=3, value=1))
INFO 执行上述代码后,Notebook 会在图表下方显示两个滑块。拖动滑块,图表会实时更新——无需重新运行单元格!这是 Jupyter 交互式计算的精髓。

IPython.display 模块

from IPython.display import display, HTML, Image, Audio, Video

# 显示 HTML
display(HTML('<h3 style="color:#f37626">自定义 HTML</h3>'))

# 显示本地图片
display(Image(filename='plot.png', width=400))

# 显示网络图片
display(Image(url='https://example.com/image.png', width=300))

# 在同一单元格显示多个输出
display(df.head())
display(df.describe())

本章小结