【问题标题】:Embedding matplotlib into a tkinter application将 matplotlib 嵌入到 tkinter 应用程序中
【发布时间】:2018-05-15 04:23:41
【问题描述】:

我有一个程序,它在启动时会打开一个比特币价格的 matplotlib 图,并且每次价格变化时都会更新。然后,当我关闭它时,会打开一个全屏 tkinter 应用程序,其中包含背景图像和角落里的更新时钟。我想要发生的是,当我启动程序时,会打开一个全屏 tkinter 应用程序,其中包含背景图像、角落的更新时钟、中间的 matplotlib 图。基本上我想将 matplotlib 图嵌入到我的应用程序中。我已经尝试将图形代码放入我的类并调用它,但这只是给出了前面提到的结果。我尝试用这个替换plt.show()

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

但随后程序根本没有启动。无论我将它放在脚本中的哪个位置,当我直接用它替换 plt.show() 时,它都会给出诸如“未定义自我”之类的错误,而当我尝试将其集成到类中时,会出现“未定义画布”之类的错误。下面是完整的代码:

from tkinter import *
from PIL import ImageTk, Image
import os
import time
import requests
import tkinter as tk
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import matplotlib.animation as animation
from matplotlib import style
from tkinter import ttk
import urllib
import json
import pandas as pd
import numpy as np
from PyQt5 import QtWidgets

fig = plt.figure()
ax1 = fig.add_subplot(1,1,1)

class App(tk.Tk):
    def __init__(self):
        # call the __init__ method of Tk class to create the main window
        tk.Tk.__init__(self)

        # background image
        img = ImageTk.PhotoImage(Image.open("0.png"))
        panel = Label(self, image=img)
        panel.pack()

        # clock
        self.label = tk.Label(self, text="", font=('comic',50,'bold'),
                          bg='#464545', fg='#1681BE')
        self.label.place(height=204, width=484, x=1384, y=824)       
        self.update_clock()

        # window geometry
        w, h = self.winfo_screenwidth(), self.winfo_screenheight()
        self.geometry("%dx%d+0+0" % (w, h))

        self.overrideredirect(True)
        self.mainloop()

    def update_clock(self):
        now = time.strftime('%H:%M:%S')
        self.label.configure(text=now)
        self.after(1000, self.update_clock)

    def animate(self): 

        dataLink = 'https://btc-e.com/api/3/trades/btc_usd?limit=2000d'
        data = urllib.request.urlopen(dataLink)
        data = data.read().decode("utf-8")
        data = json.loads(data)

        data = data["btc_usd"]
        data = pd.DataFrame(data)

        buys = data[(data['type']=="ask")]
        buys["datestamp"] = np.array(buys["timestamp"]).astype("datetime64[s]")
        buyDates = (buys["datestamp"]).tolist()

        plot(buyDates, buys["price"])

        xlabel('time')
        ylabel('Temperature')
        title('Temperature Chart')
        grid(True)


    ani = animation.FuncAnimation(fig, animate, interval=1000)

plt.show()
app = App()

有一些可靠的,例如“0.png”,它是背景图像,当然还有许多模块,但任何反馈都将不胜感激。

【问题讨论】:

  • 对不起,我没有提到这一点,但我使用的是 python 3.5.2
  • “但这也没用。”不是一个充分的问题描述。您显示的代码中没有 "something to do with canvas" ,这与从未使用过的 FigureCanvasTkAgg 的导入不同。这使得无法帮助您解决实际问题。考虑(重新)阅读How to Ask。你可以edit你的问题,而不是在它下面写cmets。

标签: python matplotlib tkinter


【解决方案1】:

plt.show() 将打开一个新的专用 GUI 窗口来托管 matplotlib 状态机中当前存在的图形。如果您不想这样,请不要使用plt.show()
为了安全起见,最好不要使用pyplot,因为即使像plt.xticks() 这样无辜的命令也可以使用cause a new window to open

另外,摆脱from pylab import *。 Pylab 是一个结构,它在单个命名空间中包含多个包,如 numpy 和 pyplot。这可能是交互式笔记本式应用程序所需要的,但对于脚本来说通常不是一个好主意,因为它使调试非常麻烦。相反,请尝试完全坚持使用 matplotlib API 命令。

这个linked question实际上是如何使用FigureCanvasTkAggNavigationToolbar2Tk将图形嵌入到tk中的示例。

一个更好的开始可能是查看 matplotlib 示例页面,其中显示了 minimal example for tk embedding

【讨论】:

    猜你喜欢
    • 2014-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-08
    • 1970-01-01
    • 2011-04-03
    • 2019-04-08
    • 2011-05-03
    相关资源
    最近更新 更多