在python中使用三个一维数组制作等高线图

Dav*_*ley 4 python contour

正如标题所示,我想通过使用三个一维数组来绘制等高线图。让我们说

x = np.array([1,2,3])
Run Code Online (Sandbox Code Playgroud)

y = np.array([1,2,3])
Run Code Online (Sandbox Code Playgroud)

z = np.array([20,21,45])
Run Code Online (Sandbox Code Playgroud)

为了在 matplotlib 中做一个轮廓图,我对xy坐标进行了网格划分,X,Y = meshgrid(x,y)但是该z数组也必须是一个二维数组。我如何然后z变成一个二维数组以便它可以使用?

np8*_*np8 8

尽管 OP 意识到不可能用问题中的数据绘制等高线图,但在可以将数据视为 3d 表面的情况下,这仍然是一个相关的问题。

三个一维阵列的轮廓绘图选项

基本上有三种选择

  1. 使用tricontourf绘制它,如果您不是绝对必须使用常规的contourf函数。适用于网格和非网格数据。
  2. 如果您的数据是网格化的,但是在三个单独的一维数组中,您可以将它们分成两个一数组和一个二维数组,并用轮廓绘制它们
  3. 如果您的数据没有网格化,并且您不想使用tricontourf,则可以将数据插入到网格中并使用contourf绘制它。有许多 3d 插值问题可以帮助您解决这个问题。插入数据后,您可以使用选项 2 中显示的技术。

选项 1:tricontourf

这个超级简单。只需像这样使用plt.tricontourf函数(参见附录中示例数据的创建)

from matplotlib import pyplot as plt

plt.tricontourf(xdata, ydata, zdata)
plt.show()
Run Code Online (Sandbox Code Playgroud)

输出

三角肌

选项 2:网格一维数组和轮廓

如果将网格数据存储在三个 1D-arrays 中,并且由于某种原因不想使用 tricontourf,则可以使用它制作一个轮廓图。(附录中给出的示例数据)

import pandas as pd
from matplotlib import pyplot as plt 

df = pd.DataFrame(dict(x=xdata, y=ydata, z=zdata))
xcol, ycol, zcol = "x", "y", "z"
df = df.sort_values(by=[xcol, ycol])
xvals = df[xcol].unique()
yvals = df[ycol].unique()
zvals = df[zcol].values.reshape(len(xvals), len(yvals)).T
plt.contourf(xvals, yvals, zvals)
plt.show()
Run Code Online (Sandbox Code Playgroud)

输出

轮廓

想法解释

  • 首先,必须对数据进行网格化,因为这是plt.contour图的工作方式。事实并非如此,您可以将其插入到新网格中。
  • 然后,创建pandas.DataFrame df作为中间媒介。
  • 然后,使用df.sort_values()方法对 x 和 y 数据进行排序。这使得unique()下一步中给出的值排序。
  • 使用 获取 x 和 y 数据的所有唯一值unique()。这有点类似于“网格网格”操作。
  • 由于 Pandas 数据框列的值只是 numpy 数组,因此您可以调用该reshape()方法来创建所需的二维数组。
  • 现在,如果 x 有 N 个唯一值,y 有 M 个唯一值,那么zvals将是一个 (N,M) 2d 数组,可以输入 plt.contour。

附录:示例数据

import numpy as np
import pandas as pd

xs, ys = np.linspace(-4, 4), np.linspace(-4, 4)
xgrid, ygrid = np.meshgrid(xs, ys)
xdata, ydata = np.ravel(xgrid), np.ravel(ygrid)
zdata = (
    2.3 * (1 - xdata) ** 2 * np.exp(-(ydata ** 2) - (xdata + 0.9) ** 2)
    - 13.3
    * (ydata / 2.2 - ydata ** 3 - xdata ** 4)
    * np.exp(-(ydata ** 2) - xdata ** 2)
    - 0.8 * np.exp(-((ydata + 1) ** 2) - xdata ** 2)
)

Run Code Online (Sandbox Code Playgroud)

  • 这是迄今为止唯一正确的答案,并且解决了所提出的问题,而且从彻底性和清晰度来看,这是一个非常好的答案。 (3认同)

id5*_*d5h -2

z的错了。它需要给出网格每个点的值。如果是和z的函数,则按我所指的计算如下:xyzX_grid

import numpy as np
import matplotlib.pyplot as plt

def f(x):
    return (x[:,0]**2 + x[:,1]**2)

x = np.array([1,2,3])
y = np.array([1,2,3])
xx, yy = np.meshgrid(x, y)
X_grid = np.c_[ np.ravel(xx), np.ravel(yy) ]
z = f(X_grid)

z = z.reshape(xx.shape)

plt.contour(xx, yy, z)
Run Code Online (Sandbox Code Playgroud)

  • 该问题询问如何从 z 值列表生成图形。它没有询问如何从函数生成图形。作为用例,它们完全不同,并且答案对于所提出的问题没有用处。也就是说,你没有回答问题。 (2认同)
  • 也许 @NP8 的正确答案是在他错误地将您标记为正确后发布的。声称因为OP选择了它,所以它是正确的,这是没有根据的。如果OP是这样的专家,他就不需要问了。 (2认同)