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

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

问题描述

基本上我在一个图形中有两个 3d 轴,一个是通过 matplotlib.animation 构建的动画,另一个是并排的 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天全站免登陆