If I have specific x and y values corresponding to a z value separated by array, how would I make a contour plot? For example:
如果我有特定的x和y值对应的z值被数组分隔,我如何绘制等高线图?例如:
Array 1 (X):
1
4
6
7
8
2
6
Array 2 (Y):
7
7
8
9
0
1
2
Array 3 (Z):
8
9
7
1
2
2
3
Would I have to do X1, Y1 = np.meshgrid(X, Y) and shape the Z array somehow? Is there another way to do this without using meshgrid? Also, if I add a fourth array and name it Z1 with the same x and y values corresponding to a particular Z1, can I plot this contour plot together with the first contour plot?
我需要用X1 Y1 = np。网格网格(X, Y)和形状的Z数组?没有网格网格,还有其他方法可以做到这一点吗?另外,如果我添加第4个数组,并将其命名为Z1,其x和y值对应于一个特定的Z1,那么我可以将这个等高线图和第一个等高线图一起绘制吗?
2 个解决方案
#1
2
If you do not have a regular grid, using triangular surface interpolation may be a good choice.
如果你没有一个规则的网格,使用三角形的表面插值可能是一个不错的选择。
In this example and the above one, if you have longer data, you only have to check the boundary of the plot.
在这个例子和上面的例子中,如果你有更长的数据,你只需要检查图的边界。
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.tri as tri
sns.set(style="white")
x = np.array([1,4,6,7,8,2,6])
y = np.array([7,7,8,9,0,1,2])
z = np.array([8,9,7,1,2,2,3])
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111)
nptsx, nptsy = 100, 100
xg, yg = np.meshgrid(np.linspace(x.min(), x.max(), nptsx),
np.linspace(y.min(), y.max(), nptsy))
triangles = tri.Triangulation(x, y)
tri_interp = tri.CubicTriInterpolator(triangles, z)
zg = tri_interp(xg, yg)
# change levels here according to your data
levels = np.linspace(0, 10, 5)
colormap = ax.contourf(xg, yg, zg, levels,
cmap=plt.cm.Blues,
norm=plt.Normalize(vmax=z.max(), vmin=z.min()))
# plot data points
ax.plot(x, y, color="#444444", marker="o", linestyle="", markersize=10)
# add a colorbar
fig.colorbar(colormap,
orientation='vertical', # horizontal colour bar
shrink=0.85)
# graph extras: look at xlim and ylim
ax.set_xlim((0, 10))
ax.set_ylim((0, 10))
ax.set_aspect("equal", "box")
plt.show()
This is the output :
这是输出:
#2
1
I think you need to do an interpolation:
我认为你需要做一个插值:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from scipy import interpolate
x = np.array([1,4,6,7,8,2,6])
y = np.array([7,7,8,9,0,1,2])
z = np.array([8,9,7,1,2,2,3])
points = np.column_stack((x,y))
values = z.T
gridx, gridy = np.mgrid[0:8:100j, 0:8:100j]
gridz = interpolate.griddata(points, values, (gridx, gridy), method='cubic')
fig = plt.figure(figsize=(12,5))
ax1 = fig.add_subplot(121,projection='3d')
ax1.plot3D(x,y,z, 'k.', ms=10)
ax1.contour(gridx,gridy,gridz)
ax2 = fig.add_subplot(122,projection='3d')
ax2.plot3D(x,y,z, 'k.', ms=10)
ax2.plot_wireframe(gridx, gridy, gridz,rstride=5,cstride=5)
plt.savefig('contour_wire.png')
This gives:
这给:
#1
2
If you do not have a regular grid, using triangular surface interpolation may be a good choice.
如果你没有一个规则的网格,使用三角形的表面插值可能是一个不错的选择。
In this example and the above one, if you have longer data, you only have to check the boundary of the plot.
在这个例子和上面的例子中,如果你有更长的数据,你只需要检查图的边界。
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.tri as tri
sns.set(style="white")
x = np.array([1,4,6,7,8,2,6])
y = np.array([7,7,8,9,0,1,2])
z = np.array([8,9,7,1,2,2,3])
fig = plt.figure(figsize=(10, 10))
ax = fig.add_subplot(111)
nptsx, nptsy = 100, 100
xg, yg = np.meshgrid(np.linspace(x.min(), x.max(), nptsx),
np.linspace(y.min(), y.max(), nptsy))
triangles = tri.Triangulation(x, y)
tri_interp = tri.CubicTriInterpolator(triangles, z)
zg = tri_interp(xg, yg)
# change levels here according to your data
levels = np.linspace(0, 10, 5)
colormap = ax.contourf(xg, yg, zg, levels,
cmap=plt.cm.Blues,
norm=plt.Normalize(vmax=z.max(), vmin=z.min()))
# plot data points
ax.plot(x, y, color="#444444", marker="o", linestyle="", markersize=10)
# add a colorbar
fig.colorbar(colormap,
orientation='vertical', # horizontal colour bar
shrink=0.85)
# graph extras: look at xlim and ylim
ax.set_xlim((0, 10))
ax.set_ylim((0, 10))
ax.set_aspect("equal", "box")
plt.show()
This is the output :
这是输出:
#2
1
I think you need to do an interpolation:
我认为你需要做一个插值:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
from scipy import interpolate
x = np.array([1,4,6,7,8,2,6])
y = np.array([7,7,8,9,0,1,2])
z = np.array([8,9,7,1,2,2,3])
points = np.column_stack((x,y))
values = z.T
gridx, gridy = np.mgrid[0:8:100j, 0:8:100j]
gridz = interpolate.griddata(points, values, (gridx, gridy), method='cubic')
fig = plt.figure(figsize=(12,5))
ax1 = fig.add_subplot(121,projection='3d')
ax1.plot3D(x,y,z, 'k.', ms=10)
ax1.contour(gridx,gridy,gridz)
ax2 = fig.add_subplot(122,projection='3d')
ax2.plot3D(x,y,z, 'k.', ms=10)
ax2.plot_wireframe(gridx, gridy, gridz,rstride=5,cstride=5)
plt.savefig('contour_wire.png')
This gives:
这给: