binnev
binnev

Reputation: 1858

Zoom an inline 3D matplotlib figure *without* using the mouse?

This question explains how to change the "camera position" of a 3D plot in matplotlib by specifying the elevation and azimuth angles. ax.view_init(elev=10,azim=20), for example.

Is there a similar way to specify the zoom of the figure numerically -- i.e. without using the mouse?

The only relevant question I could find is this one, but the accepted answer to that involves installing another library, which then also requires using the mouse to zoom.

EDIT:

Just to be clear, I'm not talking about changing the figure size (using fig.set_size_inches() or similar). The figure size is fine; the problem is that the plotted stuff only takes up a small part of the figure:

image

Upvotes: 5

Views: 4837

Answers (2)

David Sittner
David Sittner

Reputation: 31

I know this is an old question, but I thought I would provide an updated answer for anyone looking.

The ax.dist argument is being deprecated. The preferred way to do this is to use the 'zoom' argument in the ax.set_box_aspect() function.

For example:

ax.set_box_aspect((1, 1, 1), zoom=2.0)

This needs to be set before calling the figure canvas manager's show() function.

Upvotes: 3

Jan
Jan

Reputation: 248

The closest solution to view_init is setting ax.dist directly. According to the docs for get_proj "dist is the distance of the eye viewing point from the object point". The initial value is currently hardcoded with dist = 10. Lower values (above 0!) will result in a zoomed in plot.

Note: This behavior is not really documented and may change. Changing the limits of the axes to plot only the relevant parts is probably a better solution in most cases. You could use ax.autoscale(tight=True) to do this conveniently.

Working IPython/Jupyter example:

%matplotlib inline
from IPython.display import display
from mpl_toolkits.mplot3d import axes3d
import matplotlib.pyplot as plt

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

# Grab some test data.
X, Y, Z = axes3d.get_test_data(0.05)

# Plot a basic wireframe.
ax.view_init(90, 0)
ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)
plt.close()

from ipywidgets import interact

@interact(dist=(1, 20, 1))
def update(dist=10):
    ax.dist = dist
    display(fig)

Output

dist = 10

image for dist = 10

dist = 5

image for dist = 5

Upvotes: 8

Related Questions