我有一个 temperature
数组和一个 3D points
数组,这样 temperature[n]
就是 point 处的温度[n]
。如何绘制该数据的等高线图(查看 2D 平面)?
我考虑过创建一个函数 extract_plane
,其中一个平面的参数 equation
将作为参数传递,然后返回其中的点和相应的温度(这就是我需要帮助的地方)。
举个例子:
import numpy as np
import matplotlib.pyplot as plt
points = np.array([[0., 0., 0.],
[1., 0., 0.],
[1., 1., 0.],
[0., 1., 0.],
[0., 1., 1.],
[0., 0., 1.],
[1., 0., 1.],
[1., 1., 1.]])
temperature = np.array([0, 0, 0, 0, 1, 1, 1, 1.])
我需要帮助来创建以下函数。事实上,它只提取位于平面 z=0
中的点。
def extract_plane(points, temperature, equation):
"""
Given a set of 3D points, and their corresponding temperatures,
extracts a set of points that are in the plane defined by equation
along their temperatures.
Parameters
----------
points : ndarray (3D)
The set of points.
temperature : ndarray (1D)
The temperatures at the points such that temperature[n] is
the temperature in points[n].
equation : ????
The equation that defines a 2D plane (cross-section) where
the temperature is wanted to be plotted.
Returns
-------
coord : ndarray (1D)
The set of points that are in the plane defined by equation.
temp : ndarray (1D)
The set of temperatures in which temp[n] coresponds to coord[n].
"""
temp = []
coord = []
# plane z=0
for n in range(points.shape[0]):
if (points[n,2] == 0.):
temp += [temperature[n]]
coord += [points[n]]
temp = np.array(temp)
coord = np.array(coord)
return coord, temp
并使用在 this cookbook 中找到的 griddata
reshape temp
以便绘制它:
# griddata.py - 2010-07-11 ccampo
def griddata(x, y, z, binsize=0.01, retbin=True, retloc=True):
"""
Place unevenly spaced 2D data on a grid by 2D binning (nearest
neighbor interpolation).
Parameters
----------
x : ndarray (1D)
The idependent data x-axis of the grid.
y : ndarray (1D)
The idependent data y-axis of the grid.
z : ndarray (1D)
The dependent data in the form z = f(x,y).
binsize : scalar, optional
The full width and height of each bin on the grid. If each
bin is a cube, then this is the x and y dimension. This is
the step in both directions, x and y. Defaults to 0.01.
retbin : boolean, optional
Function returns `bins` variable (see below for description)
if set to True. Defaults to True.
retloc : boolean, optional
Function returns `wherebins` variable (see below for description)
if set to True. Defaults to True.
Returns
-------
grid : ndarray (2D)
The evenly gridded data. The value of each cell is the median
value of the contents of the bin.
bins : ndarray (2D)
A grid the same shape as `grid`, except the value of each cell
is the number of points in that bin. Returns only if
`retbin` is set to True.
wherebin : list (2D)
A 2D list the same shape as `grid` and `bins` where each cell
contains the indicies of `z` which contain the values stored
in the particular bin.
Revisions
---------
2010-07-11 ccampo Initial version
"""
# get extrema values.
xmin, xmax = x.min(), x.max()
ymin, ymax = y.min(), y.max()
# make coordinate arrays.
xi = np.arange(xmin, xmax+binsize, binsize)
yi = np.arange(ymin, ymax+binsize, binsize)
xi, yi = np.meshgrid(xi,yi)
# make the grid.
grid = np.zeros(xi.shape, dtype=x.dtype)
nrow, ncol = grid.shape
if retbin: bins = np.copy(grid)
# create list in same shape as grid to store indices
if retloc:
wherebin = np.copy(grid)
wherebin = wherebin.tolist()
# fill in the grid.
for row in range(nrow):
for col in range(ncol):
xc = xi[row, col] # x coordinate.
yc = yi[row, col] # y coordinate.
# find the position that xc and yc correspond to.
posx = np.abs(x - xc)
posy = np.abs(y - yc)
ibin = np.logical_and(posx < binsize/2., posy < binsize/2.)
ind = np.where(ibin == True)[0]
# fill the bin.
bin = z[ibin]
if retloc: wherebin[row][col] = ind
if retbin: bins[row, col] = bin.size
if bin.size != 0:
binval = np.median(bin)
grid[row, col] = binval
else:
grid[row, col] = np.nan # fill empty bins with nans.
# return the grid
if retbin:
if retloc:
return grid, bins, wherebin
else:
return grid, bins
else:
if retloc:
return grid, wherebin
else:
return grid
然后绘制:
coord, temp = extract_plane(points, temperature, None)
x = coord[:,0]
y = coord[:,1]
g = griddata(x, y, temp, 1., False, False)
plt.contourf(g)
最佳答案
问题中的函数看起来比实际需要的要复杂得多。使用scipy.interpolate.griddata
允许在网格上插入值。
import numpy as np
from scipy.interpolate import griddata
import matplotlib.pyplot as plt
points = np.array([[0., 0., 0.],
[1., 0., 0.],
[1., 1., 0.],
[0., 1., 0.],
[0., 1., 1.],
[0., 0., 1.],
[1., 0., 1.],
[1., 1., 1.]])
temperature = np.array([0, 0, 0, 0, 1, 1, 1, 1.])
grid_y, grid_x = np.mgrid[0:1:25j, 0:1:25j]
# equation along which to interpolate
equation = lambda x,y : 0.8*(1-x)
grid_z = equation(grid_x, grid_y)
interp = griddata(points, temperature, (grid_x, grid_y, grid_z), method='linear')
plt.subplot(121)
#plt.contourf(grid_x,grid_y, interp, origin='lower',vmin=0,vmax=1)
plt.imshow(interp, origin='lower',vmin=0,vmax=1)
plt.title('temperature along 0.8*(1-x)')
plt.xlabel("x")
plt.ylabel("y")
from mpl_toolkits.mplot3d import Axes3D
ax = plt.subplot(122, projection=Axes3D.name)
ax.scatter(points[:,0], points[:,1], points[:,2], c=temperature)
ax.set_zlim(-.1,1.1)
ax.plot_surface(grid_x,grid_y,grid_z, facecolors=plt.cm.viridis(interp),
linewidth=0, antialiased=False, shade=False)
ax.set_xlabel("x")
ax.set_ylabel("y")
plt.show()
对于 equation = lambda x,y : x*(y**.5)
:
当然使用contourf也是可以的,plt.contourf(grid_x,grid_y, interp, origin='lower',vmin=0,vmax=1)
:
关于python - 给定一组 3D 点及其相应温度的数组,如何绘制横截面的等高线图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46622391/