简体   繁体   English

Matplotlib 立方体表面的轮廓

[英]Contourf on the faces of a Matplotlib cube

I am trying to 'paint' the faces of a cube with a contourf function using Python Matplotlib.我正在尝试使用 Python Matplotlib 用轮廓函数“绘制”立方体的面。 Is this possible?这可能吗?

This is similar idea to what was done here but obviously I cannot use patches.这与这里所做的想法相似,但显然我不能使用补丁。 Similarly, I don't think I can use add_collection3d like this as it only supports PolyCollection, LineColleciton and PatchCollection.同样,我不认为我可以像这样使用 add_collection3d,因为它只支持 PolyCollection、LineColleciton 和 PatchCollection。

I have been trying to use contourf on a fig.gca(projection='3d') .我一直在尝试在fig.gca(projection='3d')上使用 contourf 。 Toy example below.下面的玩具示例。

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

plt.close('all')
fig = plt.figure()
ax = fig.gca(projection='3d')

############################################
#  plotting the 'top' layer works okay...  #
############################################

X = np.linspace(-5, 5, 43)
Y = np.linspace(-5, 5, 28)
X, Y = np.meshgrid(X, Y)

varone=np.random.rand(75,28,43)
Z=varone[0,:,:]
cset = ax.contourf(X, Y, Z, zdir='z', offset=1,
                levels=np.linspace(np.min(Z),np.max(Z),30),cmap='jet')
#see [1]
plt.show()

#################################################
#  but now trying to plot a vertical slice....  #
#################################################

plt.close('all')
fig = plt.figure()
ax = fig.gca(projection='3d')

Z=varone[::-1,:,-1]
X = np.linspace(-5, 5, 28)
Y = np.linspace(-5, 5, 75)
X, Y = np.meshgrid(X, Y)

#this 'projection' doesn't result in what I want, I really just want to rotate it
cset = ax.contourf(X, Y, Z, offset=5,zdir='x',
                levels=np.linspace(np.min(Z),np.max(Z),30),cmap='jet')

#here's what it should look like....
ax=fig.add_subplot(1, 2,1)
cs1=ax.contourf(X,Y,Z,levels=np.linspace(np.min(Z),np.max(Z),30),cmap='jet')
#see [2]    
plt.show()

1 From the example, the top surface comes easily: 1从示例中可以很容易地得到顶面:
示例图 #1

2 But I'm not sure how to do the sides. 2但我不知道如何做双方。 Left side of this plot is what the section should look like (but rotated)...该图的左侧是该部分的外观(但已旋转)...
示例图 #2

Open to other python approaches.对其他 python 方法开放。 The data I'm actually plotting are geophysical netcdf files.我实际绘制的数据是地球物理 netcdf 文件。

You have to assign the data to the right axis.您必须将数据分配到右轴。 The zig-zag results from the fact that now you are at x = const and have your oscillation in the z -direction (from the random data, which is generated between 0 and 1 ).之字形结果是因为现在您处于x = const并且在z方向上有振荡(来自随机数据,在01之间生成)。
If you you assign the matrixes differently in your example, you end up with the desired result:如果您在示例中以不同方式分配矩阵,则会得到所需的结果:

from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np

plt.close('all')
fig = plt.figure()
ax = fig.gca(projection='3d')

X = np.linspace(-5, 5, 43)
Y = np.linspace(-5, 5, 28)
X, Y = np.meshgrid(X, Y)

varone=np.random.rand(75,28,43) * 5.0 - 10.0
Z=varone[0,:,:]

cset = [[],[],[]]

# this is the example that worked for you:
cset[0] = ax.contourf(X, Y, Z, zdir='z', offset=5,
                      levels=np.linspace(np.min(Z),np.max(Z),30),cmap='jet')

# now, for the x-constant face, assign the contour to the x-plot-variable:
cset[1] = ax.contourf(Z, Y, X, zdir='x', offset=5,
                      levels=np.linspace(np.min(Z),np.max(Z),30),cmap='jet')

# likewise, for the y-constant face, assign the contour to the y-plot-variable:
cset[2] = ax.contourf(X, Z, Y, zdir='y', offset=-5,
                      levels=np.linspace(np.min(Z),np.max(Z),30),cmap='jet')

# setting 3D-axis-limits:    
ax.set_xlim3d(-5,5)
ax.set_ylim3d(-5,5)
ax.set_zlim3d(-5,5)

plt.show()

The result looks like this:结果如下所示:

等高立方体

The answer given below is not fully satisfying.下面给出的答案并不完全令人满意。 Indeed, planes in x, y and z direction reproduce the same field.实际上,x、y 和 z 方向的平面再现了相同的场。

Hereafter, a function that allows to represent the correct field in each of the planes.此后,一个允许在每个平面中表示正确场的函数。

import numpy as np
import matplotlib.pyplot as plt

def plot_cube_faces(arr, ax):
    """
    External faces representation of a 3D array with matplotlib

    Parameters
    ----------
    arr: numpy.ndarray()
        3D array to handle
    ax: Axes3D object
        Axis to work with
    """
    x0 = np.arange(arr.shape[0])
    y0 = np.arange(arr.shape[1])
    z0 = np.arange(arr.shape[2])
    x, y, z = np.meshgrid(x0, y0, z0)
    
    xmax, ymax, zmax = max(x0), max(y0), max(z0)
    vmin, vmax = np.min(arr), np.max(arr)

    ax.contourf(x[:, :, 0], y[:, :, 0], arr[:, :, -1].T,
                zdir='z', offset=zmax, vmin=vmin, vmax=vmax)
    ax.contourf(x[0, :, :].T, arr[:, 0, :].T, z[0, :, :].T,
                zdir='y', offset=0, vmin=vmin, vmax=vmax)
    ax.contourf(arr[-1, :, :].T, y[:, 0, :].T, z[:, 0, :].T,
                zdir='x', offset=xmax, vmin=vmin, vmax=vmax)

x0 = np.arange(30)
y0 = np.arange(20)
z0 = np.arange(10)
x, y, z = np.meshgrid(x0, y0, z0)
arr = (x + y + z) // 10

fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
plot_cube_faces(arr, ax)
plt.show()

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM