如何同时拖动两个3D轴

12

基本上我在一个图中有两个3D轴,一个是通过matplotlib.aninmation动画构建的,另一个是3D线性图,分别并排显示。我想添加功能,使得当您旋转一个轴时,另一个轴也跟随其旋转;例如,编写一个函数将当前视角发送到另一个轴中,如下:

angle1 = getviewingangle(ax1) 
ax2.view_init(angle1)
angle2 = getviewngangle(ax2)
ax1.view_init(angle2) 

等等。这是为了将粒子的动画路径与其预先绘制的轨迹进行比较。

2个回答

19
为了在mplot3d中同步两个子图之间的旋转,您可以将motion_notify_event连接到一个函数,该函数从旋转的图中读取角度并将其应用于相应的另一个图中。 这里是一个示例画廊,带有所描述的功能。
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()
可能还有必要同时同步缩放实用工具。在这种情况下,可以使用以下函数:
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()

你有没有考虑在 matplotllib 中为 3D 图表添加一种类似于“sharex”2D图表的“shareaxes”功能?这将非常酷。 - eric

3

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接