【问题标题】:How do I change the subplot parameters having a Figure in a window in Tkinter ? As for example I want to add the xlabel and ylabel如何在 Tkinter 的窗口中更改具有图形的子图参数?例如我想添加 xlabel 和 ylabel
【发布时间】:2020-03-09 09:58:23
【问题描述】:

我有一个应用程序应该将来自传感器的数据获取到实时图表中,即添加到图中的子图。 添加子图后,我现在遇到一个问题,我不知道如何将绘图参数更改为 xlabel、ylabel。如果我导入 plt,则此方法有效,但如果我导入将进一步添加到 Tkinter 窗口中的图形,则此方法无效。

#file livegraph.py

import matplotlib.animation as animation
import datetime

#this is a draft for the liveGraph class
#the objective is to get live data from a sensor 

class liveGraph:

    #by default define the interval as being 1000 mSec
    intervalAnim = 1000

    def __init__(self,fig):
        self.xax = 0
        self.xs = []
        self.ys = []

        self.ax = fig.add_subplot(111)
        self.ax.set_xlabel('teeeest')
        #fig.title('Graph test')
        #fig.set_xlabel("Time")
        #fig.ylabel("% SMS")

        self.anim = animation.FuncAnimation(fig, self.animate, interval = self.intervalAnim)

    def animate(self,i):

        self.xs.append(self.xax)
        self.ys.append(datetime.datetime.now().second)
        self.xax+=1

        self.ax.clear()
        self.ax.plot(self.xs,self.ys)

        if self.xax > 90:
            self.anim.event_source.stop()



from tkinter import *
from matplotlib import style
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from livegraph import liveGraph

# Define the main_screen as a tkinter
app_screen = Tk()  # create a GUI window
app_screen.geometry("1920x1080")  # set the configuration of GUI window
app_screen.resizable(width=True,height=True)
app_screen.title("Testare izolator")  # set the title of GUI window

style.use('bmh')

#figure represents the graphic part of the system
figure = Figure(figsize=(10, 5), facecolor='white',frameon=True)
figure.suptitle('This is the figure title', fontsize=12)
#figure.add_gridspec(10,10)

#this are some parameters that I can easily change if I am using plt
# plt.title('Graph test')
#plt.xlabel("Time")
#plt.ylabel("% SMS")


#x = [ 0, 1, 2, 3, 4 ]
#y = [ 0, 1, 2, 3, 4 ]
#lines = plt.plot(x, y)
#plt.grid()
#plt.axis([0,10,0,10])
#plt.setp(lines, color= "b")

canvas = FigureCanvasTkAgg(figure, app_screen)
canvas.get_tk_widget().pack(side=TOP, anchor =NW, padx=100, pady=10)

newAnimation = liveGraph(figure)

app_screen.mainloop()  # start the GUI

【问题讨论】:

  • 尝试self.ax而不是fig来添加元素。但删除 self.ax.clear() 会删除所有元素。
  • @furas 谢谢。这行得通。现在我的图表有问题。如果我要删除 .clear(),每帧都会修改线条的颜色
  • 我不确定,但它可能会在旧线上绘制新线,因此它使用不同的颜色。更好的解决方案是使用clear(),但也可以在动画的每一帧中设置标签。我在答案中添加了代码。我尝试创建在动画中使用blit=True 的示例。
  • 我更改了答案中的代码。我做了两个版本。一个人在动画中一次又一次地贴上标签。其次在开始时创建空图并使用set_data() 更改图中的数据而不使用plot(),因此不需要clear()。但它需要手动重新缩放绘图(如果你真的需要重新缩放绘图)
  • 第二种方法肯定更合适。我将使用 FuncAnimation 中的 init 函数并在那里定义它。感谢您的支持。

标签: python matplotlib tkinter figure


【解决方案1】:

你应该使用self.ax.来添加元素

    self.ax.set_xlabel('teeeest')
    self.ax.set_title('Graph test')
    self.ax.set_xlabel("Time")
    self.ax.set_ylabel("% SMS")

但是还有其他问题,因为self.ax.clear() 删除了这些元素。


第一种方法:

如果你使用self.ax.clear(),那么你删除标签,你必须一次又一次地放置标签

def animate(self, i):

    self.xs.append(self.xax)
    #self.ys.append(datetime.datetime.now().second)
    self.ys.append(random.randint(0, 10))
    self.xax += 1

    self.ax.clear()
    self.ax.plot(self.xs,self.ys)
    if self.xax > 90:
        self.anim.event_source.stop()

    self.ax.set_xlabel('teeeest')
    self.ax.set_title('Graph test')
    self.ax.set_xlabel("Time")
    self.ax.set_ylabel("% SMS")

第二种方法:

要仅在必须删除 self.ax.clear() 而不是 plot() 时添加元素,您应该在 `init

中创建空图
    self.ax = fig.add_subplot(111)
    self.ax.set_xlabel('teeeest')
    self.ax.set_title('Graph test')
    self.ax.set_xlabel("Time")
    self.ax.set_ylabel("% SMS")

    self.line, = self.ax.plot([], [])

在动画中使用set_data() 更新现有绘图中的数据

    self.line.set_data(self.xs, self.ys)

但它不会重新缩放绘图,您必须手动进行(如果您想重新缩放它)

    self.ax.relim()  # recalculate limits
    self.ax.autoscale_view(True,True,True)  # rescale using limits

第一种方法的完整代码

import matplotlib.animation as animation
import datetime
import random
#this is a draft for the liveGraph class
#the objective is to get live data from a sensor 

class liveGraph:

    #by default define the interval as being 1000 mSec
    intervalAnim = 1000

    def __init__(self, fig):
        self.xax = 0
        self.xs = []
        self.ys = []

        self.ax = fig.add_subplot(111)
        self.ax.set_xlabel('teeeest')

        self.anim = animation.FuncAnimation(fig, self.animate, interval=self.intervalAnim)

    def animate(self, i):

        self.xs.append(self.xax)
        #self.ys.append(datetime.datetime.now().second)
        self.ys.append(random.randint(0, 10))
        self.xax += 1

        self.ax.clear()
        self.ax.plot(self.xs,self.ys)
        if self.xax > 90:
            self.anim.event_source.stop()

        self.ax.set_title('Graph test')
        self.ax.set_xlabel("Time")
        self.ax.set_ylabel("% SMS")

from tkinter import *
from matplotlib import style
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
#from livegraph import liveGraph

# Define the main_screen as a tkinter
app_screen = Tk()  # create a GUI window
app_screen.geometry("1920x1080")  # set the configuration of GUI window
app_screen.resizable(width=True, height=True)
app_screen.title("Testare izolator")  # set the title of GUI window

style.use('bmh')

#figure represents the graphic part of the system
figure = Figure(figsize=(10, 5), facecolor='white', frameon=True)
figure.suptitle('This is the figure title', fontsize=12)
#figure.add_gridspec(10,10)

#this are some parameters that I can easily change if I am using plt
#plt.title('Graph test')
#plt.xlabel("Time")
#plt.ylabel("% SMS")


#x = [ 0, 1, 2, 3, 4 ]
#y = [ 0, 1, 2, 3, 4 ]
#lines = plt.plot(x, y)
#plt.grid()
#plt.axis([0,10,0,10])
#plt.setp(lines, color= "b")

canvas = FigureCanvasTkAgg(figure, app_screen)
canvas.get_tk_widget().pack(side=TOP, anchor=NW, padx=100, pady=10)

newAnimation = liveGraph(figure)

#canvas.draw()

app_screen.mainloop()  # start the GUI

第二种方法的完整代码

import matplotlib.animation as animation
import datetime
import random
#this is a draft for the liveGraph class
#the objective is to get live data from a sensor 

class liveGraph:

    #by default define the interval as being 1000 mSec
    intervalAnim = 1000

    def __init__(self, fig):
        self.xax = 0
        self.xs = []
        self.ys = []

        self.ax = fig.add_subplot(111)
        self.ax.set_xlabel('teeeest')
        self.ax.set_title('Graph test')
        self.ax.set_xlabel("Time")
        self.ax.set_ylabel("% SMS")

        # create empty plot at start    
        self.line, = self.ax.plot([], [])

        self.anim = animation.FuncAnimation(fig, self.animate, interval=self.intervalAnim)

    def animate(self, i):

        self.xs.append(self.xax)
        #self.ys.append(datetime.datetime.now().second)
        self.ys.append(random.randint(0, 2))
        self.xax += 1

        # update data in existing plot
        self.line.set_data(self.xs, self.ys)

        # rescale plot (if you need it)
        self.ax.relim()  # recalculate limits
        self.ax.autoscale_view(True,True,True)  # rescale using limits

        if self.xax > 90:
            self.anim.event_source.stop()

from tkinter import *
from matplotlib import style
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
#from livegraph import liveGraph

# Define the main_screen as a tkinter
app_screen = Tk()  # create a GUI window
app_screen.geometry("1920x1080")  # set the configuration of GUI window
app_screen.resizable(width=True, height=True)
app_screen.title("Testare izolator")  # set the title of GUI window

style.use('bmh')

#figure represents the graphic part of the system
figure = Figure(figsize=(10, 5), facecolor='white', frameon=True)
figure.suptitle('This is the figure title', fontsize=12)
#figure.add_gridspec(10,10)

#this are some parameters that I can easily change if I am using plt
#plt.title('Graph test')
#plt.xlabel("Time")
#plt.ylabel("% SMS")


#x = [ 0, 1, 2, 3, 4 ]
#y = [ 0, 1, 2, 3, 4 ]
#lines = plt.plot(x, y)
#plt.grid()
#plt.axis([0,10,0,10])
#plt.setp(lines, color= "b")

canvas = FigureCanvasTkAgg(figure, app_screen)
canvas.get_tk_widget().pack(side=TOP, anchor=NW, padx=100, pady=10)

newAnimation = liveGraph(figure)

#canvas.draw()

app_screen.mainloop()  # start the GUI

【讨论】:

    猜你喜欢
    • 2021-11-19
    • 1970-01-01
    • 2017-07-02
    • 2013-04-15
    • 2019-02-19
    • 2020-04-14
    • 2021-01-03
    • 2014-06-23
    • 1970-01-01
    相关资源
    最近更新 更多