Search code examples
pythonmatplotlibplotzoomingmatplotlib-3d

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


Solution

  • 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