如何绘制z = f(x, y)的平滑二维彩色图?

19

我想使用matplotlib绘制二维场数据。基本上,我想要类似于这个的东西:

enter image description here

在我的实际情况中,我有一个存储在硬盘上的文件中的数据。但是为了简单起见,考虑函数z = f(x,y)。我希望得到一个平滑的二维图,其中使用颜色来可视化z值。我使用以下代码进行绘图:

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(-1, 1, 21)
y = np.linspace(-1, 1, 21)
z = np.array([i*i+j*j for j in y for i in x])

X, Y = np.meshgrid(x, y)
Z = z.reshape(21, 21)

plt.pcolor(X, Y, Z)
plt.show()
然而,我得到的图很粗糙。有没有一种非常简单的方法来平滑这个图?我知道使用“surface”图类似的东西是可能的,但是那些是3D的。我可以改变摄像机角度来获得2D表示,但我相信有更简单的方法。我也尝试了“imshow”,但那时我必须在“graphic”坐标中思考,其中原点在左上角。
问题已解决
我成功解决了我的问题,使用以下命令: plt.imshow(Z,origin='lower',interpolation='bilinear')

唯一区别于你的连线图的是,你的网格更粗糙。将21改为更大的数字,比如101或1001。 - wflynny
是的,我知道,但是即使使用较少的网格点,也可以使用插值获得平滑的图形。 imshow 有这种能力。我能否使用 pcolor 做类似的事情? - Aeronaelius
请编辑您的问题,用一个代表性的例子_准确地_描述您想要的内容。 - wflynny
3个回答

13

如果您无法更改网格的粒度,请尝试使用 imshow,它可以将任何2D矩阵绘制为图像,其中每个矩阵单元格的值代表要生成该像素的颜色。使用您的示例值:

In [3]: x = y = np.linspace(-1, 1, 21)
In [4]: z = np.array([i*i+j*j for j in y for i in x])
In [5]: Z = z.reshape(21, 21)
In [7]: plt.imshow(Z, interpolation='bilinear')
Out[7]: <matplotlib.image.AxesImage at 0x7f4864277650>
In [8]: plt.show()

在此输入图片描述


我知道这一点。但是我提出的情况很简单。实际上,我有数据存储在一个 txt 文件中,所以我不能调整数据。所以,在一个简单的函数情况下,我可以这样做。但是如果是从第三方获取的数据呢? - Aeronaelius
1
谢谢,我刚刚也发现了这个。我还添加了origin='lower'作为参数,以使原点位于左下角。 - Aeronaelius

12

你可以使用contourf

plt.contourf(X, Y, Z)

enter image description here

编辑:

如果要获得更多级别(更平滑的颜色过渡),可以使用更多级别(轮廓)。

例如:

plt.contourf(X, Y, Z, 100)

输入图像描述


2
这里有明显的区域分隔。我想要一个平滑的渐变。 - Aeronaelius
2
你可以增加层数。我会提供更新的说明。 - tmdavison

1
你可以使用 pcolor 或者 pcolormesh 来完成这个任务,如果你提供了使用 Gouraud 渲染的选项。
import numpy as np
from matplotlib import pyplot as plt

y, x = np.meshgrid(np.linspace(-1, 1, 5), np.linspace(-1, 1, 5))
z = x**2+y**2
_, [ax1, ax2] = plt.subplots(1,2)
ax1.pcolormesh(x, y, z)
ax1.set_title("Default shading")
ax2.pcolormesh(x, y, z, shading='gouraud')
ax2.set_title("Gouraud shaing")

output of commands above. Plot with and without gouraud shading


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接