Plot Python Tkinter 3d tidak dapat menggeser atau memperbesar

Saya telah mencoba memasukkan plot 2d/3d menggunakan matplotlib dalam aplikasi GUI Python saya menggunakan TKinter dan berhasil dengan plot 2d, tetapi tidak dengan plot 3d. Masalah saya adalah tidak ada plot 3d yang dapat digeser atau diperbesar, meskipun tombol di panel navigasi telah merespons klik tombol. Berikut adalah contoh kode yang menunjukkan masalah saya:

import tkinter as tk

import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
import numpy as np

root = tk.Tk()
frame = tk.Frame(root)
frame.pack(side=tk.TOP, fill=tk.BOTH, expand=True)

#uncomment as needed to demonstrate 2d/3d plot
#subplot_kw = {'projection':'3d'}
subplot_kw = {}
fig, ax = plt.subplots(subplot_kw=subplot_kw)
if len(subplot_kw) > 0:
    ax.plot(range(100), np.random.rand(100), np.random.rand(100))
else:
    ax.plot(range(100), np.random.rand(100))

canvas = FigureCanvasTkAgg(fig, frame)
canvas.draw()
canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=True)

toolbar = NavigationToolbar2Tk(canvas, frame)
toolbar.update()

root.mainloop()

Jadi ketika saya memplot 2d menggunakan kode di atas, pan/zoom berfungsi seperti yang diharapkan. Ketika saya mengubah baris komentar dan menggunakan plot 3d, geser/zoom tidak berfungsi. Apakah saya melewatkan sesuatu yang sederhana atau ada masalah dengan 3d pan/zoom di tkinter dengan matplotlib?


person randomuser343884    schedule 09.01.2019    source sumber


Jawaban (1)


Pertama, jangan gunakan pyplot untuk membuat gambar yang ingin Anda sematkan di tkinter (atau GUI lainnya), karena gambar yang sama dikelola oleh pyplot serta GUI khusus Anda dapat menyebabkan berbagai macam masalah. Menggunakan matplotlib.figure.Figure (seperti yang ditunjukkan dalam contoh "Menyematkan di tk"), akan kasus ini memiliki manfaat tambahan dengan mengeluarkan peringatan tentang masalah tersebut:

UserWarning: Axes3D.figure.canvas is 'None', mouse rotation disabled. Set canvas then call Axes3D.mouse_init().

Ini pada dasarnya berarti Anda perlu memanggil mouse_init(), atau cukup membuat sumbu 3D setelah mengatur kanvas. Yang terakhir ditunjukkan di bawah ini.

import tkinter
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.backends.backend_tkagg import (
                                    FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure

root = tkinter.Tk()
root.wm_title("Embedding in Tk")

fig = Figure(figsize=(5, 4), dpi=100)

canvas = FigureCanvasTkAgg(fig, master=root)  # A tk.DrawingArea.
canvas.draw()

ax = fig.add_subplot(111, projection="3d")
t = np.arange(0, 3, .01)
ax.plot(t, 2 * np.sin(2 * np.pi * t))

toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)


tkinter.mainloop()
person ImportanceOfBeingErnest    schedule 10.01.2019
comment
terima kasih! Saya memang melihat kode contoh yang Anda daftarkan dan tidak mengerti mengapa pyplot tidak digunakan, seperti pada contoh lain yang memplot angka secara eksplisit. Saya akan memperbarui semua plot di gui saya untuk membuat objek Figure() secara langsung daripada menggunakan pyplot. - person randomuser343884; 10.01.2019
comment
Juga, tahukah Anda mengapa canvas.get_tk_widget().pack() dipanggil dua kali? Saya tidak melihat penjelasan dalam contoh dan saya tidak dapat menemukannya di dokumentasi. Saya belum melihat perbedaan dengan salah satu dari dua baris yang dikomentari. - person randomuser343884; 10.01.2019
comment
Ya, itu mungkin kesalahan dalam contohnya. Saya mengedit kode saya di atas. - person ImportanceOfBeingErnest; 10.01.2019