在python中使用三个1D数组制作等高线图

时间:2017-01-27 15:32:17

标签: python contour

正如标题所示,我想通过使用三个1D阵列来制作轮廓图。让我们说

x = np.array([1,2,3])

y = np.array([1,2,3])

z = np.array([20,21,45])

要在matplotlib中执行等高线图,我将xy坐标网格化为X,Y = meshgrid(x,y),但z数组也必须是2D数组。如何将z转换为2d数组以便可以使用?

4 个答案:

答案 0 :(得分:1)

您的z错了。它需要在网格的每个点给出值。如果zxy的函数,请根据我在下面的z计算X_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)

答案 1 :(得分:0)

在我看来,你是通过空间而不是表面描述一维曲线。我说,因为我认为x[i]y[i]z[i]是一个点的坐标。您不能使用这些点以简单的方式定义曲面,因为您的点仅依赖于一个变量i,因此仅描述具有一个自由度的形状。考虑一下,您可以将列表中的每个点连接到下一个点,并且这只会为您提供一维点链。要在三个阵列中制作曲面,必须定义9个z值,而不是3个。

我很抱歉这不是一个有用的答案,但我没有发表评论的声誉。

答案 2 :(得分:0)

我经常遇到这个问题,如果我使用的数据是为了便于操作而使用了。在分级数据中,二维阵列变平。

原始数据包含每个坐标的x,y和z值:

x = [0, 1, 2; 0, 1, 2]

y = [0, 0, 0; 1, 1, 1]

z = [0.1 , 0.2, 0.3 ; 0.2, 0.3, 0.4]

对所有三个数组使用np.ravel()使它们成为一维6元素长数组。

xx = np.ravel(x); yy = np.ravel(y) ; zz = np.ravel(z)

现在xx =([0,1,2,0,1,2]),yy和zz类似。

如果这是您正在使用的数据类型并且数据已经过彻底采样,您可以使用散点图模拟一个等高线图。这仅适用于您的数据集采样得足以填满所有空间的情况。

plt.scatter(xx,yy,c=zz,cmap=cm.Reds)

enter image description here

答案 3 :(得分:0)

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

三个一维数组的轮廓绘制选项

基本上有三个选择

  1. 如果您不必绝对使用常规的tricontourf函数,请使用contourf进行绘制。处理栅格化的非栅格化数据。
  2. 如果数据是网格化的,但是在三个单独的1d数组中,可以将它们分成两个1d数组和一个2d数组,并使用contourf进行绘制
  3. 如果您的数据不是未网格化的,并且您不想使用tricontourf,则可以将数据插值到网格中并使用contourf进行绘制。 many 3d interpolation questions可以帮助您。插入数据后,可以使用选项2中显示的技术。

选项1:tricontourf

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

from matplotlib import pyplot as plt

plt.contourf(xvals, yvals, zvals)
plt.show()

输出

tricontourf

选项2:网格1D数组和轮廓f

如果一个人将栅格数据存储在三个1D数组中,并且由于某种原因不想使用tricontourf,则可以使用它来制作contourf图。 (附录中提供的示例数据)

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()

输出

contourf

想法解释了

  • 首先,必须对数据进行网格化,因为这就是plt.contour图的工作方式。并非如此,您可以将其插值到新网格。
  • 然后,创建pandas.DataFrame df作为中间介质。
  • 然后,使用df.sort_values()方法对x和y数据进行排序。这将使unique()在下一步中给出的值进行排序。
  • 使用unique()获取x和y数据的所有唯一值。这与“ meshgrid”操作相反。
  • 由于pandas数据框列的值只是numpy数组,因此您可以调用reshape()方法来创建所需的2d数组。
  • 现在,如果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)
)