Skip to content

Python Pandas - 可视化

Pandas 直接在其 Series 和 DataFrame 对象上提供了便捷的绘图功能。这些功能本质上是对流行的 Matplotlib 库的封装,使得无需显式导入 Matplotlib(尽管必须安装 Matplotlib:pip install matplotlib)即可轻松生成常见图表。

基本的绘图方法是 .plot()。默认情况下,它会创建折线图。

import pandas as pd
import numpy as np
# 确保已安装 matplotlib: pip install matplotlib
rng = np.random.default_rng(42)
df = pd.DataFrame(rng.standard_normal((10, 4)).cumsum(axis=0), # 使用累积和以获得更有趣的线条
index=pd.date_range('2023-01-01', periods=10, freq='D'),
columns=['A', 'B', 'C', 'D'])
print("DataFrame:")
print(df)
# 生成图表(在单独窗口或笔记本中内嵌显示)
try:
plot = df.plot()
print("\n正在生成折线图...")
# 在脚本中,你可能需要 plot.figure.show() 或保存它
# plot.figure.savefig('basic_line_plot.png')
except ImportError:
print("\n未找到 Matplotlib。请安装: pip install matplotlib")
except Exception as e:
print(f"\n绘图错误 (可能发生在没有显示器的环境中): {e}")

输出描述:

这段代码生成一个折线图。DataFrame 的索引(日期)用作 x 轴,每列(‘A’、‘B’、‘C’、‘D’)在 y 轴上绘制为一条单独的有色线条。由于索引包含日期,Pandas 会自动适当地格式化 x 轴标签以提高可读性。

你可以使用某些图表类型(如散点图)中的 x 和 y 参数,将特定列相互对照绘制。

.plot() 方法通过 kind 关键字参数支持各种图表类型:

  • kind='line' (默认)
  • kind='bar' 或 kind='barh' 用于垂直或水平柱状图
  • kind='hist' 用于直方图
  • kind='box' 用于箱线图
  • kind='kde' 或 kind='density' 用于核密度估计图
  • kind='area' 用于面积图
  • kind='pie' 用于饼图
  • kind='scatter' 用于散点图

或者,你可以使用特定的方法,如 df.plot.bar()、df.plot.hist() 等。

柱状图对于比较不同类别或组的值非常有用。

import pandas as pd
import numpy as np
rng = np.random.default_rng(43)
df_bar = pd.DataFrame(rng.random((6, 4)),
index=['one', 'two', 'three', 'four', 'five', 'six'],
columns=pd.Index(['A', 'B', 'C', 'D'], name='Metrics'))
print("DataFrame for Bar Plot:")
print(df_bar)
try:
# 垂直柱状图
ax_bar = df_bar.plot(kind='bar')
# ax_bar = df_bar.plot.bar() # 等价
ax_bar.set_title('Vertical Bar Plot')
ax_bar.set_ylabel('Values')
print("\n正在生成垂直柱状图...")
# ax_bar.figure.show()
except Exception as e:
print(f"\n绘图错误: {e}")

输出描述:

这会生成一个垂直柱状图。索引标签(‘one’ 到 ‘six’)出现在 x 轴上。对于每个索引标签,有一组柱,每列(‘A’、‘B’、‘C’、‘D’)一个,显示它们各自的值。

要创建堆叠柱状图,请传递 stacked=True:

# 使用上一个示例中的 df_bar
try:
# 堆叠垂直柱状图
ax_stacked = df_bar.plot.bar(stacked=True)
ax_stacked.set_title('Stacked Vertical Bar Plot')
ax_stacked.set_ylabel('Cumulative Values')
print("\n正在生成堆叠垂直柱状图...")
# ax_stacked.figure.show()
except Exception as e:
print(f"\n绘图错误: {e}")

输出描述:

这会生成一个堆叠柱状图。对于 x 轴上的每个索引标签,有一个单独的柱,代表所有列(‘A’ 到 ‘D’)值的总和。每个柱内的段,通过颜色区分,显示每列对总和的贡献。

对于水平柱状图,使用 kind='barh' 或 .plot.barh():

# 使用上一个示例中的 df_bar
try:
# 水平堆叠柱状图
ax_barh = df_bar.plot.barh(stacked=True)
ax_barh.set_title('Horizontal Stacked Bar Plot')
ax_barh.set_xlabel('Cumulative Values')
print("\n正在生成水平堆叠柱状图...")
# ax_barh.figure.show()
except Exception as e:
print(f"\n绘图错误: {e}")

输出描述:

这会生成一个水平堆叠柱状图。索引标签现在在 y 轴上,柱横向延伸。每个柱通过颜色分段,代表每列的累积贡献。

直方图通过将值分组到箱中并显示每个箱中的值频率来可视化数值数据的分布。

import pandas as pd
import numpy as np
rng = np.random.default_rng(44)
df_hist = pd.DataFrame({
'a': rng.standard_normal(1000) + 1,
'b': rng.standard_normal(1000),
'c': rng.standard_normal(1000) - 1
}, columns=['a', 'b', 'c'])
print("用于直方图的 DataFrame:")
print(df_hist.head())
try:
# 在同一轴上绘制所有列的直方图
ax_hist = df_hist.plot.hist(bins=20, alpha=0.5) # alpha 表示透明度
ax_hist.set_title('Histogram of Columns A, B, C')
ax_hist.set_xlabel('Value')
print("\n正在生成重叠直方图...")
# ax_hist.figure.show()
except Exception as e:
print(f"\n绘图错误: {e}")

输出描述:

这会创建一个包含三个重叠直方图的图表,每列(‘a’、‘b’、‘c’)一个,使用 20 个箱。alpha=0.5 使直方图半透明,允许可视化重叠部分。它显示了每列数据的分布形状。

要在单独的子图中绘制每列的直方图,你可以迭代或使用 DataFrame 内置的 hist() 方法(它与 plot.hist() 略有不同):

# 使用上一个示例中的 df_hist
try:
# 在单独的子图中绘制直方图
axes_hist_sep = df_hist.hist(bins=20, grid=False, figsize=(10, 4)) # 返回轴数组
# 通过轴访问图形: axes_hist_sep[0,0].figure.suptitle('Separate Histograms')
print("\n正在生成单独的直方图...")
# axes_hist_sep[0,0].figure.show()
except Exception as e:
print(f"\n绘图错误: {e}")

输出描述:

这使用 df.hist() 方法生成一个包含单独子图的图表,每个子图显示一列(‘a’、‘b’ 或 ‘c’)的直方图,使用 20 个箱。这避免了重叠,使单个分布更清晰。

箱线图(或箱须图)非常适合可视化数值数据的分布和汇总统计信息(中位数、四分位数、异常值),通常用于比较不同组或列之间的分布。

import pandas as pd
import numpy as np
rng = np.random.default_rng(45)
df_box = pd.DataFrame(rng.random((10, 5)), columns=['A', 'B', 'C', 'D', 'E'])
print("用于箱线图的 DataFrame:")
print(df_box.head())
try:
# 为每列生成箱线图
ax_box = df_box.plot.box()
# ax_box = df_box.boxplot() # 类似的替代方法
ax_box.set_title('Box Plot of Columns A-E')
ax_box.set_ylabel('Value')
print("\n正在生成箱线图...")
# ax_box.figure.show()
except Exception as e:
print(f"\n绘图错误: {e}")

输出描述:

这段代码生成一个包含五个箱线图的图表,每列(‘A’ 到 ‘E’)一个。每个箱显示四分位距 (IQR)(第 25 到第 75 百分位数),中位数(箱内的线)和“须”,通常延伸到箱边缘 1.5 倍 IQR 的位置。超出须的点可能作为单个异常值绘制。

面积图类似于折线图,但填充线下的区域,常用于显示随时间变化的累积总计或贡献。

import pandas as pd
import numpy as np
rng = np.random.default_rng(46)
df_area = pd.DataFrame(rng.random((10, 4)), columns=['a', 'b', 'c', 'd'])
print("用于面积图的 DataFrame:")
print(df_area.head())
try:
# 生成一个堆叠面积图(默认)
ax_area = df_area.plot.area()
ax_area.set_title('Stacked Area Plot')
ax_area.set_ylabel('Cumulative Value')
print("\n正在生成堆叠面积图...")
# ax_area.figure.show()
except Exception as e:
print(f"\n绘图错误: {e}")

输出描述:

这会生成一个堆叠面积图。y 轴表示在 x 轴上每个索引位置处的列值的累积总和。每个有色区域表示特定列对总堆叠的贡献。

散点图用于可视化两个数值变量之间的关系。每个点代表一个观测值。

import pandas as pd
import numpy as np
rng = np.random.default_rng(47)
df_scatter = pd.DataFrame(rng.random((50, 4)), columns=['a', 'b', 'c', 'd'])
print("用于散点图的 DataFrame (前 5 行):")
print(df_scatter.head())
try:
# 生成列 'a' vs 'b' 的散点图
ax_scatter = df_scatter.plot.scatter(x='a', y='b')
ax_scatter.set_title('Scatter Plot of Column B vs Column A')
ax_scatter.set_xlabel('Value of Column A')
ax_scatter.set_ylabel('Value of Column B')
print("\n正在生成散点图...")
# ax_scatter.figure.show()
except Exception as e:
print(f"\n绘图错误: {e}")

输出描述:

这会创建一个散点图,其中每个点的水平位置由列 ‘a’ 中的值确定,垂直位置由列 ‘b’ 中的值确定。它有助于直观检查这两个变量之间的相关性或模式。

饼图表示整体的比例或百分比。它们最适合用于少量类别。

import pandas as pd
import numpy as np
# 创建一个适合饼图的 Series(正值)
series_pie = pd.Series(3 * np.abs(np.random.randn(4)), index=['a', 'b', 'c', 'd'], name='Proportions')
print("用于饼图的 Series:")
print(series_pie)
try:
# 从 Series 生成饼图
# autopct 格式化百分比显示
ax_pie = series_pie.plot.pie(autopct='%.1f%%', figsize=(5, 5))
ax_pie.set_title('Pie Chart Example')
ax_pie.set_ylabel('') # 移除默认的 y 轴标签(通常是 Series 名称)
print("\n正在生成饼图...")
# ax_pie.figure.show()
except Exception as e:
print(f"\n绘图错误: {e}")

输出描述:

这段代码从 series_pie 生成一个饼图。每个扇形代表一个索引标签(‘a’、‘b’、‘c’、‘d’),扇形的大小与 Series 中相应的值成比例。百分比显示在扇形上。

关于可视化库的说明: 虽然 Pandas 内置的绘图功能对于快速探索很方便,但 Seaborn(基于 Matplotlib 构建,提供更多面向统计的图表和更好的美观性)和 Plotly(创建交互式图表)等库提供了更高级的功能和定制选项。对于更复杂的可视化需求,可以考虑探索这些库。