从 2x1 子图中删除 xticks 或 xticklabel 之一

问题描述 投票:0回答:1

我正在制作一个 GUI,显示 4 个不同读数的图表。现在读数是随机生成的。我使用 matplotlib 和动画来显示实时读数,其中 2 个读数共享一个子图,另外两个显示在另一个子图上。在 x 轴上,我显示当前时间读数。

我对 python 比较陌生,所以我不确定其中一些东西是如何工作的。我的问题很可能是我有答案,但不知道如何应用它们。

这是我的代码:


import tkinter as tk 
from tkinter import *
from tkinter import ttk

import matplotlib 
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
import matplotlib.pyplot as plt #to plot the graph
import matplotlib.animation as animation #to create the real-time graph
from matplotlib import style #to change the way the graph will look
import matplotlib.ticker as mticker

import numpy as np
import datetime as dt

#-----------------------------END OF IMPORT -----------------------------------------------#
matplotlib.use("TkAgg") #backend of matplotlib??
style.use("dark_background") 
LARGE_FONT = ("Times New Roman", 12)
NORM_FONT = ("Times New Roman", 9)
colors = ('tab:red','tab:blue')
#----------------------------------FUNCTION------------------------------------------------#

fig1 = plt.figure(0)
ax11 = fig1.add_subplot(211)

ax12 = ax11.twinx()

ax21 = fig1.add_subplot(212,sharex=ax11)
ax22 = ax21.twinx()

xList1= []
yList11=[]
yList12=[]

xList2= []
yList21=[]
yList22=[]


def animate_graph(i,x1,y11,y12,ax11
                  ,ax12
                  ,x2
                  ,y21,y22,ax21,ax22
                  ):


    a = (2-1)*np.random.random()+1
    b = (4-3)*np.random.random()+3
    c = (6-5)*np.random.random()+5
    d = (8-7)*np.random.random()+7


    x1.append(dt.datetime.now().strftime('%H:%M:%S'))
    y11.append(a)
    y12.append(b)

    x2.append(dt.datetime.now().strftime('%H:%M:%S'))
    y21.append(c)
    y22.append(d)


    x1 = x1[-10:]
    y11 = y11[-10:]
    y12 = y12[-10:]

    x2 = x2[-10:]
    y21 = y21[-10:]
    y22 = y22[-10:]


    ax11.clear()
    ln1 = ax11.plot(x1,y11,colors[0],label = 'Temp(C)')
    ax11.tick_params(axis = 'y',labelcolor = colors[0])


    ax12.clear()
    ln2 = ax12.plot(x1,y12,colors[1],label = 'RH(%?)')
    ax12.tick_params(axis = 'y',labelcolor = colors[1])


    lns1 = ln1 + ln2
    labs1 = [l.get_label() for l in lns1]
    ax11.legend(lns1,labs1,bbox_to_anchor = (0,1.02,1,0.102),loc = 3,ncol = 3,borderaxespad = 0)

    ax21.clear()
    ln3 = ax21.plot(x2,y21,colors[0],label = 'CO(%)')
    ax21.tick_params(axis = 'y',labelcolor = colors[0])
    

    ax22.clear()
    ln4 = ax22.plot(x2,y22,colors[1],label = 'CO2(%)')

    ax22.tick_params(axis = 'y',labelcolor = colors[1])

    lns2 = ln3 + ln4
    labs2 = [l.get_label() for l in lns2]
    ax21.legend(lns2,labs2,bbox_to_anchor = (0,1.02,1,0.102),loc = 3,ncol = 3,borderaxespad = 0)

    ax11.tick_params(axis = 'x',labelrotation = 45)
    
    ax21.tick_params(axis = 'x',labelrotation = 45)

#----------------------------------MAIN-------------------------------#
class main(tk.Tk):
    
    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self,*args,**kwargs)
        tk.Tk.title(self, "Hubba Dub")
        
        container = tk.Frame(self)
        container.pack(side = "top" , fill = "both" , expand = True)
        container.grid_rowconfigure(0, weight = 1)
        container.grid_columnconfigure(0,weight = 1)

        menubar = tk.Menu(self,tearoff=0)

        filemenu = menubar.add_command(label= "Exit", command=quit)
        menubar.add_cascade(label="File",menu= filemenu)

        playpausemenu = menubar.add_command(label= "Pause", command=0)
        menubar.add_cascade(label  = "Pause/Play",menu=playpausemenu)


        self.frames = {}

        for f in (StartPage,GraphAll):
            frame = f(container,self)
            self.frames[f] = frame
            frame.grid(row = 0,column = 0, sticky = "nsew")

        self.show_frame(StartPage)

    def show_frame(self,cont):
        frame = self.frames[cont]
        frame.tkraise()

class StartPage(tk.Frame):
    
    def __init__(self,parent,control):
        tk.Frame.__init__(self,parent)

        label = ttk.Label(self,text = "StartPage", font = LARGE_FONT)
        label.pack(pady = 10, padx = 10)
        
        b1 = ttk.Button(self,text = "Open page to display sensor data", command = lambda: control.show_frame(GraphAll))
        b1.pack()

        b3 = ttk.Button(self,text = "Exit", command = quit)
        b3.pack()

class GraphAll(tk.Frame):
    def __init__(self,parent,control):
        tk.Frame.__init__(self,parent)
        
        label = ttk.Label(self,text = "Show All Readings",font = LARGE_FONT)
        label.pack()

        b1 = ttk.Button(self,text = "Pause", command = lambda: anim.event_source.stop())
        b1.pack()

        b2 = ttk.Button(self,text = "Play", command = lambda: anim.event_source.start())
        b2.pack()

        b3 = ttk.Button(self,text = "Exit",command= quit)
        b3.pack()

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

        toolbar = NavigationToolbar2Tk(canvas,self)
        toolbar.update()
        canvas._tkcanvas.pack(side=tk.TOP,fill = tk.BOTH,expand = True)



# call main class
gui = main()   
# gui.geometry("1280x720")
gui.state('zoomed') #maximise window
anim = animation.FuncAnimation(fig1,animate_graph,
                               fargs=(xList1,yList11,yList12,ax11
                                      ,ax12
                                      ,xList2,yList21,yList22,ax21,ax22
                                      )
                                      ,interval= 1000
                                      )
#run in loop
gui.mainloop()

这是graphing page。您可以看到这里的读数显示正确。唯一的问题是 x 轴读数显示在两个而不是一个上。

我认为通过使用 sharex,它只会显示底部图上的 x 轴,而不是顶部图,但这并没有改变任何东西,这让我感到惊讶,因为这应该有效。

我尝试使用 set_xticks

set_xticks([])
但我没有看到任何变化。也许我做得不对,但我不确定问题到底出在哪里。

我从这个

问题
中发现了get_xticklines(),但这似乎也不起作用。

如有任何帮助,我们将不胜感激。谢谢。

subplot tkinter-canvas matplotlib-animation
1个回答
0
投票

我发现了问题所在。所以事实证明,问题只是缺乏 Python 编程经验。

我正在关注sentdex的youtube播放列表来制作GUI。我在那里找到了问题的答案。

我在

plt.setp(ax21.get_xticklabels(),visible = False)
函数中添加了这一行
animate_graph
。代码块如下所示。


#setup second axis of plot 2
    ax22.clear()
    ln4 = ax22.plot(x2,y22,colors[1],label = 'CO2(%)')
    ax22.tick_params(axis = 'y',labelcolor = colors[1])

    #---------------------------------------------#
    #set the x-axis tick labels visibility to False
    plt.setp(ax21.get_xticklabels(),visible = False)
    #----------------------------------------------#
    
    #keep two legends from the two axes together. legends belong to an axis. In our case, we have two y-axis, so two separate legend made rather than together
    lns2 = ln3 + ln4
    labs2 = [l.get_label() for l in lns2]
    ax21.legend(lns2,labs2,bbox_to_anchor = (0,-0.1,1,0)
                # (0,1.02,1,0.102)
                ,loc = 'lower left',ncol = 3,borderaxespad = 0)

然后我得到了这个image。第二个子图的图例需要移动,所以我意识到

bbox_to_anchor
中的
ax21.legend()
参数应该更改为
(0,-0.1,1,0)
。现在我明白了image

一切都按照我想要的方式进行。我很高兴:)

© www.soinside.com 2019 - 2024. All rights reserved.