Suche…


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 Achsen erstellen

Matplotlib-Achsen sind standardmäßig zweidimensional. Um dreidimensionale Diagramme zu erstellen, müssen Sie die Axes3D Klasse aus dem mplot3d-Toolkit importieren , um eine neue Art der Projektion für Achsen zu ermöglichen, nämlich '3d' :

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

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

Neben den einfachen Verallgemeinerungen von zweidimensionalen Plots (wie Liniendiagramme , Streudiagramme , Balkendiagramme , Liniendiagramme ), mehr Oberflächen Plotten Methoden zur Verfügung, beispielsweise ax.plot_surface :

# generate example data
import numpy as np
x,y = np.meshgrid(np.linspace(-1,1,15),np.linspace(-1,1,15))
z = np.cos(x*np.pi)*np.sin(y*np.pi)

# actual plotting example
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
# rstride and cstride are row and column stride (step size)
ax.plot_surface(x,y,z,rstride=1,cstride=1,cmap='hot')
ax.set_xlabel(r'$x$')
ax.set_ylabel(r'$y$')
ax.set_zlabel(r'$\cos(\pi x) \sin(\pi y)$')
plt.show()

Axes3D mit Oberflächenplot



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow