แปลง Python Tkinter 3d ไม่สามารถเลื่อนหรือซูมได้

ฉันพยายามรวมแปลง 2d/3d โดยใช้ matplotlib ในแอปพลิเคชัน Python GUI ของฉันโดยใช้ TKinter และประสบความสำเร็จกับแปลง 2d แต่ไม่ใช่แปลง 3 มิติ ปัญหาของฉันคือไม่สามารถแพนหรือซูมแปลง 3 มิติได้ แม้ว่าปุ่มในบานหน้าต่างนำทางจะตอบสนองต่อการคลิกปุ่มก็ตาม นี่คือตัวอย่างโค้ดที่แสดงให้เห็นถึงปัญหาของฉัน:

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

ดังนั้นเมื่อฉันพล็อต 2d โดยใช้โค้ดด้านบน การแพน/ซูมจะทำงานตามที่คาดไว้ เมื่อฉันเปลี่ยนบรรทัดที่แสดงความคิดเห็นและใช้พล็อต 3 มิติ การแพน/ซูมจะไม่ทำงาน ฉันขาดอะไรง่ายๆ หรือมีปัญหากับการแพน / ซูม 3 มิติใน tkinter ด้วย matplotlib หรือไม่


person randomuser343884    schedule 09.01.2019    source แหล่งที่มา


คำตอบ (1)


ขั้นแรก อย่าใช้ pyplot เพื่อสร้างฟิกเกอร์ที่คุณต้องการฝังใน tkinter (หรือ GUI อื่นๆ) เนื่องจากการมีฟิกเกอร์เดียวกันที่จัดการโดย pyplot และ GUI ที่คุณกำหนดเองอาจทำให้เกิดปัญหาได้ทุกประเภท การใช้ matplotlib.figure.Figure (ดังที่แสดงใน ตัวอย่าง "Embedding in tk") จะอยู่ใน กรณีนี้มีประโยชน์เพิ่มเติมในการส่งคำเตือนเกี่ยวกับปัญหา:

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

โดยพื้นฐานแล้วหมายความว่าคุณต้องเรียก mouse_init() หรือเพียงสร้างแกน 3 มิติ หลังจาก ตั้งค่าผืนผ้าใบ หลังแสดงอยู่ด้านล่าง

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
ขอบคุณ! ฉันเห็นโค้ดตัวอย่างที่คุณระบุไว้แล้ว และไม่เข้าใจว่าทำไมจึงไม่ใช้ pyplot ดังตัวอย่างอื่นๆ ที่พล็อตตัวเลขไว้อย่างชัดเจน ฉันจะอัปเดตแปลงทั้งหมดใน gui ของฉันเพื่อสร้างวัตถุ Figure() โดยตรงแทนที่จะใช้ pyplot - person randomuser343884; 10.01.2019
comment
คุณรู้ไหมว่าทำไม canvas.get_tk_widget().pack() จึงถูกเรียกสองครั้ง ฉันไม่เห็นคำอธิบายในตัวอย่าง และไม่พบคำอธิบายในเอกสารประกอบ ฉันไม่ได้สังเกตเห็นความแตกต่างกับหนึ่งในสองบรรทัดที่แสดงความคิดเห็น - person randomuser343884; 10.01.2019
comment
ใช่ นั่นอาจเป็นการกำกับดูแลในตัวอย่างนี้ ฉันแก้ไขโค้ดของฉันด้านบน - person ImportanceOfBeingErnest; 10.01.2019