Looking for matplotlib Keywords? Try Ask4Keywords

matplotlibDreidimensionale Diagramme


Bemerkungen

Das dreidimensionale Plotten in Matplotlib war in der Vergangenheit etwas schwierig, da die Rendering-Engine inhärent 2d ist. Die Tatsache, dass 3D-Setups durch das Plotten eines 2d-Blocks nach dem anderen gerendert werden, bedeutet, dass häufig Rendering-Probleme mit der scheinbaren Tiefe von Objekten verbunden sind. Der Kern des Problems besteht darin, dass zwei nicht verbundene Objekte entweder vollständig hintereinander oder vollständig voreinander sein können, was zu Artefakten führt, wie in der folgenden Abbildung zweier ineinandergreifender Ringe dargestellt (Klicken Sie für ein animiertes GIF):

Plot 3d von zwei ineinandergreifenden Ringen, die Artefakt zeigen

Dies kann jedoch behoben werden. Dieses Artefakt ist nur vorhanden, wenn mehrere Flächen in derselben Zeichnung geplottet werden - da jede als flache 2D-Form dargestellt wird, wobei ein einzelner Parameter den Sichtabstand bestimmt. Sie werden feststellen, dass eine einzelne komplizierte Oberfläche nicht das gleiche Problem aufweist.

Abhilfe schaffen Sie, indem Sie die Plotobjekte mithilfe von transparenten Brücken zusammenfügen:

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

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

X = np.arange(0, 6, 0.25)
Y = np.arange(0, 6, 0.25)
X, Y = np.meshgrid(X, Y)

Z1 = np.empty_like(X)
Z2 = np.empty_like(X)
C1 = np.empty_like(X, dtype=object)
C2 = np.empty_like(X, dtype=object)

for i in range(len(X)):
  for j in range(len(X[0])):
    z1 = 0.5*(erf((X[i,j]+Y[i,j]-4.5)*0.5)+1)
    z2 = 0.5*(erf((-X[i,j]-Y[i,j]+4.5)*0.5)+1)
    Z1[i,j] = z1
    Z2[i,j] = z2

    # If you want to grab a colour from a matplotlib cmap function, 
    # you need to give it a number between 0 and 1. z1 and z2 are 
    # already in this range, so it just works as is.
    C1[i,j] = plt.get_cmap("Oranges")(z1)
    C2[i,j] = plt.get_cmap("Blues")(z2)


# Create a transparent bridge region
X_bridge = np.vstack([X[-1,:],X[-1,:]])
Y_bridge = np.vstack([Y[-1,:],Y[-1,:]])
Z_bridge = np.vstack([Z1[-1,:],Z2[-1,:]])
color_bridge = np.empty_like(Z_bridge, dtype=object)

color_bridge.fill((1,1,1,0)) # RGBA colour, onlt the last component matters - it represents the alpha / opacity.

# Join the two surfaces flipping one of them (using also the bridge)
X_full = np.vstack([X, X_bridge, np.flipud(X)])
Y_full = np.vstack([Y, Y_bridge, np.flipud(Y)])
Z_full = np.vstack([Z1, Z_bridge, np.flipud(Z2)])
color_full = np.vstack([C1, color_bridge, np.flipud(C2)])

surf_full = ax.plot_surface(X_full, Y_full, Z_full, rstride=1, cstride=1,
                            facecolors=color_full, linewidth=0,
                            antialiased=False)

plt.show()

Zwei sich kreuzende Flächen Geben Sie hier die Bildbeschreibung ein

Dreidimensionale Diagramme Verwandte Beispiele