2015-09-10 1 views
3

J'ai deux orbites qui se produisent à différentes hauteurs. Je les trace en 3D, mais je souhaite les joindre avec une surface. Jusqu'à présent, j'ai cette image: enter image description hereComment joindre ces deux lignes 3D ensemble avec une surface dans matplotlib de Python

que je me utiliser ce script:

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

font = {'size' : 18} 
matplotlib.rc('font', **font) 

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

#Read in data 
data = np.genfromtxt('mu8.txt') 
x, y = np.hsplit(data, 2) 
N = len(x) 
z = np.zeros(N) 
z[:,] = 8.0 

#Plot the first orbit 
ax.plot(x, y, z, 'k-', linewidth=3.0) 

#Read in data for second orbit 
data = np.genfromtxt('mu9.txt') 
x2, y2 = np.hsplit(data, 2) 
N = len(x2) 
z2 = np.zeros(N) 
z2[:,] = 9.0 

#Plot second orbit 
ax.plot(x2, y2, z2, 'k-', linewidth=3.0) 

#Join together the data for both orbits 
xx = np.concatenate((x, x2), axis=0) 
yy = np.concatenate((y, y2), axis=0) 
zz = np.concatenate((z, z2), axis=0) 

#Plot the surface 
surf = ax.plot_surface(xx,yy,zz, color='m', alpha=0.3, 
     linewidth=0) 

#Set axis and things 
ax.set_xticks([1.0,1.5,2]) 
ax.set_yticks([32,35,38]) 
ax.set_ylabel('$||u||_{2}$', fontsize=26, rotation=0, labelpad = 26) 
ax.set_xlabel('$h$', fontsize=26) 
ax.set_zlabel('$\mu$', fontsize=26, rotation=90) 
plt.tight_layout() 

plt.show() 

Comme vous le voyez - cela ne semble pas très bon. Ma motivation pour vouloir faire ceci est que j'ai beaucoup plus de ces orbites que j'ai besoin de tracer, toutes à des hauteurs différentes. Lorsque la hauteur change, les orbites deviennent plus petites. Je pense que la meilleure façon de visualiser cela est de les assembler avec une surface - de cette façon, les orbites traceront un cylindre déformé, à double canon, qui rétrécira et pincera à la fin. Y a-t-il un moyen de faire cela?

Je voudrais pouvoir faire quelque chose dans le style de cette: enter image description here

+0

Intéressant. Je suis un peu surpris que vous en ayez une surface - est-ce que 'data' a quatre colonnes? Qu'en est-il de la figure que vous avez affichée avec laquelle vous n'êtes pas satisfait? En outre, les orbites ont-elles chacune le même nombre de points? –

+0

S'agit-il d'orbites paramétriques, de sorte que vous puissiez dessiner des lignes verticales à chaque fois (ou peu importe) _t_? – cphlewis

+0

Oui, ce sont des orbites paramétriques - en particulier, elles représentent les emplacements des solutions à une équation différentielle pour différentes valeurs de paramètres. Les orbites ont le même nombre de points ou de nœuds. Les données ont 3 colonnes (x, y, z). Je suis insatisfait de la figure que j'ai posté parce que la surface ne se rejoignent pas, à la place elle pend verticalement comme un rideau de douche. Je veux que ça colle aux lignes. –

Répondre

2

Vous voulez trouver l'équation de la ligne reliant le point ième dans la première orbite au point ième dans la deuxième orbite. Ensuite, vous pouvez utiliser i et z en tant que paramètres, variant sur toutes les valeurs possibles pour trouver X et Y.

Exemple:

import numpy as np 
import matplotlib 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 
Z1 = 8.0 
Z2 = 9.0 
font = {'size' : 18} 
matplotlib.rc('font', **font) 

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

t = np.linspace(0, 2 * np.pi, 100) 
x = np.cos(t) 
y = np.sin(2 * t) 
N = len(x) 
z = np.zeros(N) 
z[:,] = Z1 

t = np.linspace(0, 2 * np.pi, 100) 
x2 = 2 * np.cos(t) 
y2 = 2 * np.sin(2*t) 
N = len(x2) 
z2 = np.zeros(N) 
z2[:,] = Z2 

#Plot the first orbit 
ax.plot(x, y, z, 'k-', linewidth=3.0) 
#Plot second orbit 
ax.plot(x2, y2, z2, 'k-', linewidth=3.0) 


i, h = np.meshgrid(np.arange(len(x)), np.linspace(Z1, Z2, 10)) 
X = (x2[i] - x[i])/(Z2 - Z1) * (h - Z1) + x[i] 
Y = (y2[i] - y[i])/(Z2 - Z1) * (h - Z1) + y[i] 
surf = ax.plot_surface(X, Y, h, color='m', alpha=0.3, 
     linewidth=0) 


#Set axis and things 
ax.set_xticks([1.0,1.5,2]) 
ax.set_yticks([32,35,38]) 
ax.set_ylabel('$||u||_{2}$', fontsize=26, rotation=0, labelpad = 26) 
ax.set_xlabel('$h$', fontsize=26) 
ax.set_zlabel('$\mu$', fontsize=26, rotation=90) 
plt.tight_layout() 

plt.show() 

image of two orbits connected by a surface

+0

J'ai mis à jour, mais matplotlib ne semble pas rendre les bords correctement. – denfromufa