J'ai besoin de visualiser des ensembles de données multivariés complexes et le choix préférable est d'utiliser une modification de la visualisation de l'axe parallèle, en utilisant des graphes 2D empilés, où chaque tracé cartographie un degré de liberté les points appartenant aux mêmes ensembles de données devraient être interconnectés entre différentes parcelles. Je joins un croquis conceptuel. Comment pourrais-je l'implémenter dans matplotlib
?Graphiques 2D empilés avec des interconnexions dans Matplotlib
1
A
Répondre
2
Pour avoir une idée approximative, cela pourrait être une solution possible à l'aide matplotlib Axes3D
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle, PathPatch
import mpl_toolkits.mplot3d.art3d as art3d
x = np.array([1,2,3])
y = np.array([2,3,1])
z = np.array([1,1,1])
fig = plt.figure(figsize=(6,6))
ax = fig.add_axes([0,0,1,1], projection='3d')
#plot the points
ax.scatter(x,y,z*0.4, c="r", facecolor="r", s=60)
ax.scatter(y,x,z*0.9, c="b", facecolor="b", s=60)
ax.scatter(x,y,z*1.6, c="g", facecolor="g", s=60)
#plot connection lines
ax.plot([x[0],y[0],x[0]],[y[0],x[0],y[0]],[0.4,0.9,1.6], color="k")
ax.plot([x[2],y[2],x[2]],[y[2],x[2],y[2]],[0.4,0.9,1.6], color="k")
#plot planes
p = Rectangle((0,0), 4,4, color="r", alpha=0.2)
ax.add_patch(p)
art3d.pathpatch_2d_to_3d(p, z=0.4, zdir="z")
p = Rectangle((0,0), 4,4, color="b", alpha=0.2)
ax.add_patch(p)
art3d.pathpatch_2d_to_3d(p, z=0.9, zdir="z")
p = Rectangle((0,0), 4,4, color="g", alpha=0.2)
ax.add_patch(p)
art3d.pathpatch_2d_to_3d(p, z=1.6, zdir="z")
ax.set_aspect('equal')
ax.view_init(13,-63)
ax.set_xlim3d([0,4])
ax.set_ylim3d([0,4])
ax.set_zlim3d([0,2])
plt.savefig(__file__+".png")
plt.show()
Mise à jour
Création de trois axes différents est possible. Il faut ajouter les axes et rendre les plus transparents (ax2.patch.set_alpha(0.)
). Ensuite, la grille doit être désactivée (ax.grid(False)
) et les volets et les lignes dont nous n'avons pas besoin sont invisibles.
Cependant, je n'ai aucune idée comment dessiner une connexion entre les axes. L'approche 2D de matplotlib.patches.ConnectionPatch
ne fonctionne pas pour les axes 3D.
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle
import mpl_toolkits.mplot3d.art3d as art3d
x = np.array([1,2,3])
y = np.array([2,3,1])
z = np.array([0,0,0])
fig = plt.figure(figsize=(6,6))
ax = fig.add_axes([0,0,1,1], projection='3d')
ax2 = fig.add_axes([0.0,0.24,1,1], projection='3d')
ax2.patch.set_alpha(0.)
ax3 = fig.add_axes([0.0,0.48,1,1], projection='3d')
ax3.patch.set_alpha(0.)
#plot the points
ax.scatter(x,y,z, c="r", facecolor="r", s=60)
ax2.scatter(y*4,x*4,z, c="b", facecolor="b", s=60)
ax3.scatter(x*100,y*100,z, c="g", facecolor="g", s=60)
#plot connection lines
#ax.plot([x[0],y[0],x[0]],[y[0],x[0],y[0]],[0.4,0.9,1.6], color="k")
#ax.plot([x[2],y[2],x[2]],[y[2],x[2],y[2]],[0.4,0.9,1.6], color="k")
#plot planes
p = Rectangle((0,0), 4,4, color="r", alpha=0.2)
ax.add_patch(p)
art3d.pathpatch_2d_to_3d(p, z=0, zdir="z")
p = Rectangle((0,0), 16,16, color="b", alpha=0.2)
ax2.add_patch(p)
art3d.pathpatch_2d_to_3d(p, z=0, zdir="z")
p = Rectangle((0,0), 400,400, color="g", alpha=0.2)
ax3.add_patch(p)
art3d.pathpatch_2d_to_3d(p, z=0, zdir="z")
ax.set_aspect('equal')
ax2.set_aspect('equal')
ax3.set_aspect('equal')
ax.view_init(13,-63)
ax2.view_init(10,-63)
ax3.view_init(8,-63)
ax.set_xlim3d([0,4])
ax.set_ylim3d([0,4])
ax.set_zlim3d([0,2])
ax2.set_xlim3d([0,16])
ax2.set_ylim3d([0,16])
ax2.set_zlim3d([0,2])
ax3.set_xlim3d([0,400])
ax3.set_ylim3d([0,400])
ax3.set_zlim3d([0,2])
ax.grid(False)
ax2.grid(False)
ax3.grid(False)
def axinvisible(ax):
for zax in (ax.w_zaxis, ax.w_xaxis, ax.w_yaxis):
zax.pane.set_visible(False)
if zax == ax.w_zaxis:
zax.line.set_visible(False)
for ll in zax.get_ticklines()+zax.get_ticklabels():
ll.set_visible(False)
axinvisible(ax)
axinvisible(ax2)
axinvisible(ax3)
# setting a ConnectionPatch does NOT work
from matplotlib.patches import ConnectionPatch
con = ConnectionPatch(xyA=(2,2), xyB=(2,2),
coordsA='data', coordsB='data',
axesA=ax, axesB=ax2,
arrowstyle='->', clip_on=True)
ax2.add_artist(con) # artist is not shown :-(
plt.show()
0
Une solution pourrait être basée sur matplotlib's 3D capabilities. Vous pouvez utiliser Axes3D.plot_surface
pour tracer les axes, et la dispersion de l'utilisateur et les tracés de ligne pour le reste.
Merci. Cependant, les rectangles que j'ai spécifiés ci-dessus sont supposés être des plans de données/axes différents. Ce qui signifie, ils représentent différents paramètres et représentent donc des points dans différents espaces. Donc je crois qu'il y a au moins deux problèmes: (i) dessiner des axes empilés (cela devrait être relativement facile); (ii) interconnecter des points entre différents axes (ce sera difficile, car le seul moyen est d'avoir une métrique incluant tous les points ...) – maurizio
Je n'ai pas encore résolu le problème des graphes empilés, ce qui devrait être relativement simple , mais pour les connexions entre les tracés, 'matplotlib.patches.ConnectionPatch' devrait faire l'affaire, bien que le doc ne dise pas si cette méthode fonctionne sur les objets' Axes3D' ... – maurizio
J'ai résolu le problème des graphes empilés (voir mise à jour) . Mais je n'ai aucune idée de comment les connecter. – ImportanceOfBeingErnest