旋转嵌入式matplotlib图

时间:2015-05-19 16:14:26

标签: python python-3.x matplotlib plot tkinter

我使用matplotlib创建了一个相当简单的Basemap图,然后我使用matplotlib文档中的大纲将其嵌入到tkinter框架中,并引用此处发布的问题作为好。我已经查看了我发现的有关将matplotlib绘图嵌入到tkinter框架中的其他问题,但仍无法找到解决此问题的方法。或者,我尝试了不同的方法来创建画布/框架,因为我怀疑这是通过在类和其他方法之外移动框架创建所在的真正问题所在。当我使用下面的方法并且包括使用exit()destroy()关闭窗口的tkinter按钮时,我得到最大递归深度错误。

然而,由于某些原因,我仍然无法旋转嵌入的绘图,如果我取消注释下面的行,即使我在代码块中注释,我也可以旋转绘图。这对我来说没有意义,因为它似乎完全是多余的,它只是创建了另一个空白窗口然后我被允许再次旋转绘图出于某些我不理解的原因。

作为另一个尝试过的解决方案,我尝试使用Axes3D.init_mouse正如我所看到的那样发布作为类似问题的答案,但这也不起作用。

以下是相关的代码块

class GUI(tk.Tk):
    def __init__(self, parent):
        tk.Tk.__init__(self, parent)
        self.parent = parent
        self.fig = None
        self.map = None
        self.axes = None
        self.polygon_border = "black"


    def init_plot(self):

        self.fig = plot.figure()
        self.map = Basemap()
        self.axes = Axes3D(self.fig)
        self.axes.azim = 270
        self.axes.elev = 50
        self.axes.dist = 10
        self.axes.add_collection3d(self.map.drawcoastlines(linewidth = 0.25))
        self.axes.add_collection3d(self.map.drawcountries(linewidth = 0.35))
        self.axes.add_collection3d(self.map.drawstates(linewidth = 0.1))

        self.create_polygons()
        self.fig = self.axes.get_figure()

        #uncommenting the below line allows for rotation inside of tkitner albeit very slowly and somewhat crudely
        #plot.show()

   def init_frame(self):

        self.frame = tk.Frame(self)
        self.frame.pack()
        self.canvas = FigureCanvasTkAgg(self.fig, master = self.frame)
        self.canvas.show()
        #Axes3D.mouse_init(self.fig)
        self.canvas.get_tk_widget().pack(fill = "both", expand = True)
        self.toolbar = NavigationToolbar2TkAgg(self.canvas, self)
        self.toolbar.update()
        self.toolbar.pack()
        self.canvas._tkcanvas.pack(side = tk.TOP, fill = tk.BOTH, 
                                    expand = True)

1 个答案:

答案 0 :(得分:3)

以下是我最终的解决方案,简化形式。我的结构有问题,其中一些self.canvas需要在将3D轴添加到画布之前创建,否则会导致Axes3D.mouse_init错误,它不允许旋转,因为它无法找到画布。我假设这就是为什么被注释掉的冗余行在取消注释时允许轮换的原因。

此外,您需要使用plot中的pyplot而非figure,否则来自Basemap的多边形将显示错误。

如果以上所有内容都准确无法100%确定,但这是我在游戏和测试后发现的。

from mpl_toolkits.mplot3d import Axes3D #For plotting 3D Axes
from mpl_toolkits.basemap import Basemap #For plotting polygonal surfaces
from matplotlib.collections import PolyCollection #Polygons
import matplotlib.pyplot as plot
import matplotlib, sys     
matplotlib.use("TkAgg")
from matplotlib.backnds.backend_tkagg import FigureCanvasTkAgg,\
    NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import tkinter as tk


root = tk.Tk()
f = plot.figure(figsize = (5, 5), dpi = 100)
canvas = FigureCanvasTkAgg(f, master = root)
axes = Axes3D(f)

map = Basemap()

axes.add_collection3d(map.drawcoastlines(linewidth = 0.3, color = "white"))
axes.add_collection3d(map.drawcountries(linewidth = 0.3, color = "white"))
axes.add_collection3d(map.drawstates(linewidth = 0.3, color = "white"))


polygons = []
for polygon in map.landpolygons:
    polygons.append(polygon.get_coords())
    collection = PolyCollection(polygons, edgecolor = "white",
                               facecolor = "black", 
                            closed = True)

axes.add_collection3d(collection)


canvas.show()
canvas.get_tk_widget().pack(side = tk.BOTTOM, fill = tk.BOTH, expand = 1)
canvas._tkcanvas.pack(side = tk.BOTTOM, fill = tk.BOTH, expand = 1)
button = tk.Button(master = root, text = "Exit", command = sys.exit)
button.pack(side = tk.TOP)

tk.mainloop()