You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于Pandas DataFrame的三列数据(x、y、z)使用Pandas和Matplotlib绘制2D标量图(如imshow或contour)

如何基于Pandas DataFrame的三列数据(x、y、z)使用Pandas和Matplotlib绘制2D标量图(如imshow或contour)

我完全懂你的感受——明明是很基础的需求,居然一开始没找到纯Pandas+Matplotlib的方案,还要用到Seaborn。其实不用Seaborn也能轻松实现,核心是先把你的长格式DataFrame转换成网格状的宽格式数据,然后直接用Matplotlib的绘图函数就行,下面给你两种常用的实现方式:

方法一:用imshow绘制热力图

这和你用Seaborn画的heatmap效果类似,步骤很简单:

  1. 先通过pivot把数据转成宽格式:把x作为列、y作为索引,z作为对应的值,这样就得到了二维的矩阵,刚好符合imshow的输入要求。
  2. 用Matplotlib的imshow绘制,再补充坐标轴标签、颜色条等细节。

完整代码如下:

import pandas as pd
import matplotlib.pyplot as plt

# 你的原始数据
d = {'x': [1, 1, 1, 2, 2, 2],
     'y': [1, 2, 3, 1, 2, 3],
     'z': [30, 31, 33, 10, 8, 6]}
df = pd.DataFrame(data=d)

# 将长格式数据转为宽格式(网格状)
df_pivoted = df.pivot(columns='x', index='y', values='z')

# 绘制imshow热力图
fig, ax = plt.subplots()
im = ax.imshow(df_pivoted, cmap='RdYlGn', aspect='auto')

# 添加颜色条,并设置标签
cbar = plt.colorbar(im)
cbar.set_label('z')

# 设置坐标轴标签
ax.set_xlabel('x')
ax.set_ylabel('y')

# 设置坐标轴刻度(因为pivot后的columns和index就是x、y的取值)
ax.set_xticks(range(len(df_pivoted.columns)))
ax.set_xticklabels(df_pivoted.columns)
ax.set_yticks(range(len(df_pivoted.index)))
ax.set_yticklabels(df_pivoted.index)

# 反转y轴,让y值从下往上递增(和常规认知一致)
ax.invert_yaxis()

plt.show()

方法二:用contour/contourf绘制等高线图

如果想要画等高线(填充或非填充),同样先处理数据,然后利用pivot后的索引和列生成网格,再调用Matplotlib的等高线函数:

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

# 原始数据同上
d = {'x': [1, 1, 1, 2, 2, 2],
     'y': [1, 2, 3, 1, 2, 3],
     'z': [30, 31, 33, 10, 8, 6]}
df = pd.DataFrame(data=d)

df_pivoted = df.pivot(columns='x', index='y', values='z')

# 获取x、y的网格数据
x = df_pivoted.columns.values
y = df_pivoted.index.values
X, Y = np.meshgrid(x, y)
Z = df_pivoted.values

# 绘制填充等高线图(contourf)+ 等高线(contour)
fig, ax = plt.subplots()
contour_filled = ax.contourf(X, Y, Z, cmap='RdYlGn')
contour_lines = ax.contour(X, Y, Z, colors='black')

# 添加颜色条和标签
cbar = plt.colorbar(contour_filled)
cbar.set_label('z')

ax.set_xlabel('x')
ax.set_ylabel('y')

# 添加等高线数值标签
ax.clabel(contour_lines, inline=True, fontsize=10)

plt.show()

补充说明

你之前尝试meshgrid遇到的问题,其实是因为一开始数据是长格式的,没有先转成规整的网格矩阵。通过pivot处理后,数据已经是x、y每个组合对应的z值,此时再用meshgrid生成网格就很顺畅了——当然如果是imshow的话,甚至不需要手动生成网格,直接用pivot后的DataFrame.values就行。

备注:内容来源于stack exchange,提问作者TeddyD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 14:18:12