Using Matplotlib 3D axes, how to drag two axes at once

后端 未结 1 1066
刺人心
刺人心 2020-12-03 16:08

Basically I have two 3d axes in one figure, one animated built through matplotlib.aninmation and one 3d line plot, side by side. I\'d like to add functionality so that when

相关标签:
1条回答
  • 2020-12-03 16:45

    In order to synchronize the rotation between two subplots in mplot3d you can connect the motion_notify_event to a function that reads the angles from rotated plot and applies it to the respective other plot.

    Here is an example from the gallery with the described functionality added.

    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:
            ax2.view_init(elev=ax.elev, azim=ax.azim)
        elif event.inaxes == ax2:
            ax.view_init(elev=ax2.elev, azim=ax2.azim)
        else:
            return
        fig.canvas.draw_idle()
    
    c1 = fig.canvas.mpl_connect('motion_notify_event', on_move)
    
    
    plt.show()
    

    It may make sense to additionally synchronize the zooming utility as well. In this case one may use the following function

    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()
    
    0 讨论(0)
提交回复
热议问题