2015-08-08 12 views
14

Hier ist ein Barebone Beispiel:Wie beschneide ich ein Axes3D-Diagramm mit quadratischem Seitenverhältnis?

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() 

Dies ist, was ich bekommen:

square viewports

Dies ist, was ich will:

rectangular viewports

Mit anderen Worten, ich möchte die Plots selbst haben ein quadratisches Seitenverhältnis, nicht alle gestreckt wie folgt:

stretched out

und ich habe diesen Teil Arbeiten durch https://stackoverflow.com/a/31364297/125507

aber ich möchte die Fenster in jene Plots suchen rechteckig, mit oben und unten heraus abgeschnitten (da es nur Leerraum sein wird oben und unten und ich generiere mehrere animierte GIFs, so kann ich es nicht einfach auf die Form nachbearbeiten, die ich will).

Im Grunde mache ich diese Animation, und ich möchte das Gleiche, aber ohne alle Leerzeichen:

animation

+0

ich nicht usre bin Ihr Beispiel repräsentativ genug ist, haben Sie versucht, ' fig.plots_adjust (oben = 1, unten = 0, rechts = 1, links = 0, hspace = 0, wspace = 0) '? – rll

+0

Abgesehen davon, müssen Sie Ihre 'r' – rll

+0

@rll festziehen. Yeah Ich verkürzte eine Achse von dem, was ich eigentlich will, um zu veranschaulichen, dass sie alle die gleiche Länge haben – endolith

Antwort

3

Um von settting ein auf meine Kommentare und zeigen Beispiele folgen zu lassen kleine r und Entfernen subplot Ränder mit 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() 

Dies wird straffer Nebenhandlungen geben, da die Standardeinstellungen für SubplotParams sind wie folgt:

links: 0,125

rechts: 0,9

unten: 0,1

oben: 0,9

wspace : 0,2

hspace: 0,2

nicht sicher, es ist dies die OP sucht obwohl ...

enter image description here

+0

jedes Diagramm ist immer noch quadratisch, obwohl ich sie Rechtecke machen wollen, während immer noch die gleichen Achsen haben – endolith

-1

Da Sie rechteckige Grundstück möchten, können Sie nicht set_aspect('equal') verwenden, anstatt Sie die Grenzen Ihrer Plots einstellen müssen, um berücksichtigen den Unterschied in Seitenverhältnissen.

Bei dem Versuch, unten habe ich die bbox der Achse verwendet, um die height und width der Achsen zu erhalten und verwendet, um das Seitenverhältnis X und Y Achsen neu zu skalieren.(Ich nehme an, dass beide Plots die gleiche Dimension haben, aber Sie könnten auch Plots mit unterschiedlichen Dimensionen haben, Sie müssen nur die Achsenlimits unabhängig voneinander anpassen).

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() 

Hinweis: In diesem Bild habe ich eine Hintergrundfarbe hinzugefügt, um die rechteckige Form der Flächen zu markieren

+0

sie nicht beibehalten Seitenverhältnis, wenn aber gedreht. Das Ansichtsfenster muss zu einem Rechteck beschnitten werden, das nicht zu einem geschrumpft ist – endolith