Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[feature request] multiple 3d plots with tied viewing angles #11181

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
samuela opened this issue May 7, 2018 · 8 comments · Fixed by #25821
Closed

[feature request] multiple 3d plots with tied viewing angles #11181

samuela opened this issue May 7, 2018 · 8 comments · Fixed by #25821

Comments

@samuela
Copy link

samuela commented May 7, 2018

I have a figure with a number of 3d subplots that are all showing basically the same things. I'd really love to have a way to rotate any one of these plots in the UI and have all of the others adjust their viewing angles to match, ideally in real-time.

@ImportanceOfBeingErnest
Copy link
Member

ImportanceOfBeingErnest commented May 7, 2018

You may always connect those subplots through events. A possible solution is given in this Stackoverflow answer of mine: Using Matplotlib 3D axes, how to drag two axes at once?

Code here for completeness
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
import matplotlib.pyplot as plt
import numpy as np

n_angles = 36
n_radii = 8

radii = np.linspace(0.125, 1.0, n_radii)
angles = np.linspace(0, 2*np.pi, n_angles, endpoint=False)
angles = np.repeat(angles[..., np.newaxis], n_radii, axis=1)

x = np.append(0, (radii*np.cos(angles)).flatten())
y = np.append(0, (radii*np.sin(angles)).flatten())
z = np.sin(-x*y)

fig = plt.figure( figsize=(13,6))
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0)
ax = fig.add_subplot(1, 2, 1, projection='3d')
ax2 = fig.add_subplot(1, 2, 2, projection='3d')

ax.plot_trisurf(x, y, z, cmap=cm.jet, linewidth=0.2)
ax2.plot_trisurf(x, y, z, cmap=cm.viridis, linewidth=0.5)

def on_move(event):
    if event.inaxes == ax:
        if ax.button_pressed in ax._rotate_btn:
            ax2.view_init(elev=ax.elev, azim=ax.azim)
        elif ax.button_pressed in ax._zoom_btn:
            ax2.set_xlim3d(ax.get_xlim3d())
            ax2.set_ylim3d(ax.get_ylim3d())
            ax2.set_zlim3d(ax.get_zlim3d())
    elif event.inaxes == ax2:
        if ax2.button_pressed in ax2._rotate_btn:
            ax.view_init(elev=ax2.elev, azim=ax2.azim)
        elif ax2.button_pressed in ax2._zoom_btn:
            ax.set_xlim3d(ax2.get_xlim3d())
            ax.set_ylim3d(ax2.get_ylim3d())
            ax.set_zlim3d(ax2.get_zlim3d())
    else:
        return
    fig.canvas.draw_idle()

c1 = fig.canvas.mpl_connect('motion_notify_event', on_move)

plt.show()

I guess one could easily extent this functionality to any amount of axes, but I currently wouldn't know where in the code to put that. As a figure level method? Or a new class? Using a Grouper object?

@anntzer
Copy link
Contributor

anntzer commented May 7, 2018

fwiw I feel like a recipe such as the one you proposed is good enough...

@ImportanceOfBeingErnest
Copy link
Member

The problem with this recipe above is that it uses the "private" _rotate_btn and _zoom_btn. I'm personally not very stringent about using such attributes, but I guess if proposing this as some "official strategy" (e.g. as example on the matplotlib site) people wouldn't like it.

@dstansby
Copy link
Member

dstansby commented May 7, 2018

I think this would be a nice new feature - kind of like sharex and sharey, but for 3D plots.

@ImportanceOfBeingErnest
Copy link
Member

Yep, just mind that rotation is a priori independent on sharing. You might synchronize the viewing angle, but not share the axes or vice versa. This is easily accounted for when manually creating the callback, but for some automated option it will require two independent groupers or similar.
Not saying this shouldn't be implemented, but I suppose there are much more important features in the mplot3d category to fix/implement first.

@samuela
Copy link
Author

samuela commented May 7, 2018

cc @nfoti

@QuLogic QuLogic linked a pull request Sep 3, 2020 that will close this issue
@github-actions
Copy link

github-actions bot commented May 5, 2023

This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!

@github-actions github-actions bot added the status: inactive Marked by the “Stale” Github Action label May 5, 2023
@story645
Copy link
Member

story645 commented May 5, 2023

Attn @scottshambaugh ?

@github-actions github-actions bot removed the status: inactive Marked by the “Stale” Github Action label May 6, 2023
@QuLogic QuLogic added this to the v3.8.0 milestone May 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
6 participants