2015-08-08 9 views
14

Oto Barebone przykład:Jak przyciąć wykres Axes3D o kwadratowym współczynniku kształtu?

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

fig = plt.figure() 
f = fig.add_subplot(2, 1, 1, projection='3d') 
t = fig.add_subplot(2, 1, 2, projection='3d') 

# axes 
for d in {f, t}: 
    d.plot([-1, 1], [0, 0], [0, 0], color='k', alpha=0.8, lw=2) 
    d.plot([0, 0], [-1, 1], [0, 0], color='k', alpha=0.8, lw=2) 
    d.plot([0, 0], [0, 0], [-1, 1], color='k', alpha=0.8, lw=2) 

f.dist = t.dist = 5.2 # 10 is default 

plt.tight_layout() 
f.set_aspect('equal') 
t.set_aspect('equal') 

r = 6 
f.set_xlim3d([-r, r]) 
f.set_ylim3d([-r, r]) 
f.set_zlim3d([-r, r]) 

t.set_xlim3d([-r, r]) 
t.set_ylim3d([-r, r]) 
t.set_zlim3d([-r, r]) 

f.set_axis_off() 
t.set_axis_off() 

plt.draw() 
plt.show() 

To co mam:

square viewports

To jest to, co chcę:

rectangular viewports

Innymi słowy, chcę same wątki mają kwadratowy współczynnik kształtu, nie wszystkie rozciągnięte w ten sposób:

stretched out

i dostałem tę rolę dzięki roboczą do https://stackoverflow.com/a/31364297/125507

ale chcę okna patrząc na tych działkach być prostokątny, przy czym górna i dolna wykadrowane (ponieważ nie będzie tylko spacje na górze i na dole i generuję wiele animowanych GIF-ów, więc nie mogę go łatwo przetworzyć na żądany kształt).

Zasadniczo Robię animację, a ja chcę to samo, ale bez wszystkich spacji:

animation

+0

nie jestem usre Twój przykład jest wystarczająco reprezentatywne, czy próbowałeś ' fig.subplots_adjust (top = 1, bottom = 0, right = 1, left = 0, hspace = 0, wspace = 0) '? – rll

+0

Poza tym, musisz dokręcić "r" – rll

+0

@rll Tak, skróciłem jedną oś z tego, co faktycznie chcę, aby zilustrować je wszystkie o tej samej długości. – endolith

Odpowiedz

3

Aby śledzić moje komentarze i przedstawiają przykłady przez settting mniejsze r i usuwanie marginesy subplot wykorzystujące subplots_adjust:


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

fig = plt.figure() 
f = fig.add_subplot(2, 1, 1, projection='3d') 
t = fig.add_subplot(2, 1, 2, projection='3d') 

# axes 
for d in {f, t}: 
    d.plot([-1, 1], [0, 0], [0, 0], color='k', alpha=0.8, lw=2) 
    d.plot([0, 0], [-1, 1], [0, 0], color='k', alpha=0.8, lw=2) 
    d.plot([0, 0], [0, 0], [-1, 1], color='k', alpha=0.8, lw=2) 

f.dist = t.dist = 5.2 # 10 is default 

plt.tight_layout() 
f.set_aspect('equal') 
t.set_aspect('equal') 

r = 1 
f.set_xlim3d([-r, r]) 
f.set_ylim3d([-r, r]) 
f.set_zlim3d([-r, r]) 

t.set_xlim3d([-r, r]) 
t.set_ylim3d([-r, r]) 
t.set_zlim3d([-r, r]) 

f.set_axis_off() 
t.set_axis_off() 

fig.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0, 
      hspace = 0, wspace = 0) 

plt.draw() 
plt.show() 

W ten sposób mocniej wątków jako wartości domyślne SubplotParams są następujące:

lewej: 0,125

właściwej 0,9

dolną 0.1

górną 0,9

wspace : 0.2

hspace: 0,2

nie, czy jest to PO szuka choć ...

enter image description here

+0

każdy wykres jest nadal kwadratowy, chociaż chcę, aby były prostokąty, a jednocześnie mają równe osie – endolith

-1

Ponieważ chcesz prostokątną działkę, nie można używać set_aspect('equal'), zamiast trzeba dostosować granice swoich działek uwzględniają różnicę w proporcjach.

W poniższej próbie, Użyłem bbox osi, aby uzyskać height i width z osiami i używane proporcje do przeskalowania X i Y osie.(Zakładam, że oba wykresy mają ten sam wymiar, ale możesz również mieć wykresy o różnych wymiarach, musisz dostosować limity osi niezależnie dla każdego z nich).

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

fig = plt.figure() 
f = fig.add_subplot(2, 1, 1, projection='3d') 
t = fig.add_subplot(2, 1, 2, projection='3d') 

# axes 
for d in {f, t}: 
    d.plot([-1, 1], [0, 0], [0, 0], color='k', alpha=0.8, lw=2) 
    d.plot([0, 0], [-1, 1], [0, 0], color='k', alpha=0.8, lw=2) 
    d.plot([0, 0], [0, 0], [-1, 1], color='k', alpha=0.8, lw=2) 

f.dist = t.dist = 5.2 # 10 is default 

plt.tight_layout() 
# Cannot use 'equal' aspect for a rectangular plot 
# f.set_aspect('equal') 
# t.set_aspect('equal') 

# get the dimensions of the axes from its bbox 
f_bbox = f.get_position() 
f_height = f_bbox.height 
f_width = f_bbox.width 


r = 6 
f.set_xlim3d([-1 * f_width/f_height * r, f_width/f_height * r]) 
f.set_ylim3d([-1 * f_width/f_height * r, f_width/f_height * r]) 
f.set_zlim3d([-r, r]) 

t.set_xlim3d([-1 * f_width/f_height * r, f_width/f_height * r]) 
t.set_ylim3d([-1 * f_width/f_height * r, f_width/f_height * r]) 
t.set_zlim3d([-r, r]) 

f.set_axis_off() 
t.set_axis_off() 

plt.draw() 
plt.show() 

Uwaga: W tym obrazie, dodałem kolor tła, aby zaznaczyć prostokątny kształt działek

+0

nie zachowują proporcji po obróceniu. okienko ekranu musi zostać przycięte do prostokąta, a nie skrócone do jednego – endolith

Powiązane problemy