matplotlib icon indicating copy to clipboard operation
matplotlib copied to clipboard

[ENH]: Add ability to snap view to primary axis planes in 3D plots

Open scottshambaugh opened this issue 3 years ago • 3 comments

Problem

In matlab, you can right-click on a 3D plot and a context menu pops up that gives you the option to 'Go to X-Y view', 'Go to X-Z view', and 'Go to Y-Z view'. The view then snaps to viewing that plane face-on. Something similar would be very useful in matplotlib.

image

Proposed solution

Either a right-click menu or a toolbar dropdown with similar snapping options. That would then set the appropriate ax.view_init(elev, azim, roll) elevation and azimuth view angles.

scottshambaugh avatar Aug 03 '22 17:08 scottshambaugh

Here are the view angles I would propose. This matches matlab's conventions and keeps the roll angle at 0. The inverse views show the other 3 sides of the box, and are defined by a 180 deg rotation about the local vertical axis. Might be worth a PR at some point to make all the axes in these orientations show along the bottom and left edges. (Edit: see https://github.com/matplotlib/matplotlib/pull/23644)

image

import matplotlib.pyplot as plt

# (view, (elev, azim, roll))
views = [( 'XY', (90, -90, 0)), 
         ( 'XZ', (0, -90, 0)),  
         ( 'YZ', (0, 0, 0)), 
         ('-XY', (-90, 90, 0)), 
         ('-XZ', (0, 90, 0)),
         ('-YZ', (0, 180, 0)), 
        ]

fig, axs = plt.subplots(2, 3, subplot_kw={'projection': '3d'})
for i, ax in enumerate([ax for ax_row in axs for ax in ax_row]):
    ax.set_xlabel('x')
    ax.set_ylabel('y')
    ax.set_zlabel('z')
    ax.set_title(views[i][0])
    ax.set_proj_type('ortho')
    ax.view_init(elev=views[i][1][0], azim=views[i][1][1], roll=views[i][1][2])

scottshambaugh avatar Aug 03 '22 17:08 scottshambaugh

This requires adding a right-click menu in a backend independent way? I think that will be a huge benefit in general as well, being a right-click person...

oscargus avatar Aug 10 '22 09:08 oscargus

Yeah, I see the scope of this as twofold.

  1. Programmatic interface to look at primary view planes. I think https://github.com/matplotlib/matplotlib/pull/23600 is good enough to suffice this, but maybe we accept "XY", etc. strings as an input to view_init as well.

  2. Right-click context menu to expose this to the gui. That's a pretty big chunk of work I'd expect.

scottshambaugh avatar Aug 10 '22 17:08 scottshambaugh