如何使用鼠标在 wxPython 中旋转 matplotlib 3D 图?

How to use mouse to rotate matplotlib 3D plots in wxPython?

这是我用来在 wxPython 应用程序中显示 2D matplotlib 图的代码片段:

import matplotlib
matplotlib.use('WXAgg')
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.figure import Figure
import wx

[wxPython application and class code snipped]

    figure = Figure()
    axes = figure.add_subplot(111)
    canvas = FigureCanvasWxAgg(self, wx.ID_ANY, figure)
    plotSizer = wx.BoxSizer(wx.VERTICAL)
    plotSizer.Add(self, canvas, proportion=1, flag=wx.EXPAND)
    plotPanel = wx.Panel(self, wx.ID_ANY, size=DEFAULT_PLOT_SIZE)
    plotPanel.SetSizer(plotSizer)

我可以绘制坐标轴、重绘 canvas 以及平移和缩放。当我尝试使用 3D 执行等效操作时,会显示 3D 图,但我不能 rotate/pan/zoom。此代码中的唯一区别是额外导入 3D 和向 add_subplot() 添加投影参数。

import matplotlib
matplotlib.use('WXAgg')
from mpl_toolkits.mplot3d import axes3d
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg
from matplotlib.figure import Figure
import wx

[wxPython application and class code snipped]

    figure = Figure()
    axes = figure.add_subplot(111, projection="3d")
    canvas = FigureCanvasWxAgg(self, wx.ID_ANY, figure)
    plotSizer = wx.BoxSizer(wx.VERTICAL)
    plotSizer.Add(self, canvas, proportion=1, flag=wx.EXPAND)
    plotPanel = wx.Panel(self, wx.ID_ANY, size=DEFAULT_PLOT_SIZE)
    plotPanel.SetSizer(plotSizer)

我收到此警告:

...\site-packages\mpl_toolkits\mplot3d\axes3d.py:1009: UserWarning: Axes3D.figure.canvas is 'None', mouse rotation disabled.  Set canvas then call Axes3D.mouse_init().

所以我尝试在调用 FigureCanvasWxAgg() 后使用此代码设置 Axes3D.figure.canvas:

axes.figure.canvas = canvas
axes.mouse_init()

但这行不通;我仍然无法使用鼠标旋转 3D 图。

http://matplotlib.org/mpl_toolkits/mplot3d/tutorial.html 处的演示源代码使用独立的 matplotlib 工作;我可以用鼠标旋转那里的图。使用 wxPython 时如何使鼠标旋转正常工作?

原来我只需要交换 canvas 和轴创建的顺序。 canvas 应首先创建并添加到图中,然后才能创建 3D 轴。

figure = Figure()
canvas = FigureCanvasWxAgg(self, wx.ID_ANY, figure)
axes = figure.add_subplot(111, projection="3d")
plotSizer = wx.BoxSizer(wx.VERTICAL)
plotSizer.Add(self, canvas, proportion=1, flag=wx.EXPAND)
plotPanel = wx.Panel(self, wx.ID_ANY, size=DEFAULT_PLOT_SIZE)
plotPanel.SetSizer(plotSizer)