使用Matplotlib 3D轴,如何一次拖动两个轴 [英] Using Matplotlib 3D axes, how to drag two axes at once

查看:128
本文介绍了使用Matplotlib 3D轴,如何一次拖动两个轴的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

基本上,我在一个图中有两个3d轴,一个通过matplotlib.aninmation构建的动画和一个3d线图并排放置.我想添加功能,以便当您旋转一个轴时,另一个跟随它的旋转.例如,将当前视角发送到另一个轴的功能,例如;

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 you rotate one axis, the other follows it's rotation; so for example a function that sends the current viewing angle to the other axis like;

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

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

etc. This is for comparing the animated path of a particle with it's pre-plotted trajectory.

推荐答案

为了使mplot3d中两个子图之间的旋转同步,您可以将motion_notify_event连接到一个函数,该函数从旋转图读取角度并将其应用于各自的其他情节.

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()

这篇关于使用Matplotlib 3D轴,如何一次拖动两个轴的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆