鱼C论坛

 找回密码
 立即注册
查看: 2665|回复: 16

[已解决]关于tkinter与matplotlib结合使用的一个问题

[复制链接]
发表于 2020-9-1 10:21:22 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 差不多先生air 于 2020-9-1 14:27 编辑

正常的时候界面是这样的:


但是当我调用matplotlib弹出一个生成图片的窗口时,我的界面会突然收缩一下,变成下面这样的:


我已经设置过界面不可拉伸了,请问一下是什么原因导致界面会突然收缩。。。
最佳答案
2020-9-1 15:45:47
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from tkinter import *

class testme:
    def __init__(self,frame1):
        self.frame1=frame1
        self.button=Button(self.frame1,text="DRAWME",command=self.plot)
        self.button1=Button(self.frame1,text="CLEARME",command=self.clearme)
        self.button.pack()
        self.button1.pack()

    def plot(self):
        f=Figure(figsize=(5,1))
        aplt=f.add_subplot(111)
        aplt.plot([1,2,3,4])
        self.wierdobject = FigureCanvasTkAgg(f, master=self.frame1)
        self.wierdobject.get_tk_widget().pack()
        self.wierdobject.draw()

    def clearme(self):
       self.wierdobject.get_tk_widget().pack_forget()

root=Tk()
aframe=Frame(root)
testme(aframe)
aframe.pack()  #packs a frame which given testme packs frame 1 in testme
root.mainloop()

网上找到这样一段代码,应该是你要实现的功能,看着改改试试呗
9@T@)IC@L7(D)ZMJH2G0H(G.png
8H)$G%~]C0J8_81_Y)E[{O8.png

机械特性数据测试.zip

6.13 KB, 下载次数: 1

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-9-1 11:19:07 | 显示全部楼层
tkinter做的ui,期间有用到matplotlib,pandas,numpy第三方库,打包成exe会么?
现在遇到的问题是:用 pyinstaller xxx.py -D -w 打包出来的exe一直弹错。
“Failed to execute script ui”
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-1 14:15:01 | 显示全部楼层
rsj0315 发表于 2020-9-1 11:19
tkinter做的ui,期间有用到matplotlib,pandas,numpy第三方库,打包成exe会么?
现在遇到的问题是:用 py ...

你用源代码编译的时候,调用matplotlib函数的时候,界面会变形吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-1 14:19:34 | 显示全部楼层
差不多先生air 发表于 2020-9-1 14:15
你用源代码编译的时候,调用matplotlib函数的时候,界面会变形吗?

你把代码放上来看看吧

用rsj0315的代码,窗口界面不变形的

你用他的代码也可以试一下,看看会不会有问题
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-1 14:25:20 | 显示全部楼层
疾风怪盗 发表于 2020-9-1 14:19
你把代码放上来看看吧

用rsj0315的代码,窗口界面不变形的
from tkinter import *
import matplotlib.pyplot as plt
from tkinter import  filedialog
import openpyxl as xl

root = Tk()

root.geometry('595x560')  # 设置窗口大小
root.title('综合测试平台       Author:**')  # 设置根窗口标题

def excel_():
    def get_data(path):
        wb = xl.load_workbook(path,data_only=True)
        ws = wb.active

        hezha_lst = []
        A_lst = []
        B_lst = []
        C_lst = []

        for row in ws.iter_rows(min_row=2,max_row=4,min_col=1,max_col=4):
            # print(row[0].value,row[4].value)
            hezha_lst.append(row[0].value)
            A_lst.append(row[1].value)
            B_lst.append(row[2].value)
            C_lst.append(row[3].value)
            
        return hezha_lst,A_lst,B_lst,C_lst

    def chart(x,y1,y2,y3):
        plt.plot(x,y1,label='A相')
        plt.scatter(x,y1,color='r') 
        plt.plot(x,y2,label='B相')
        plt.scatter(x,y2,color='g') 
        plt.plot(x,y3,label='C相')
        plt.scatter(x,y3,color='b') 
        plt.title('合闸数据分析')
        plt.legend()
        plt.show()

    path = filedialog.askopenfilename(title='选择Excel文件路径', filetypes=[('*.xlsx', '.xlsx')])
    plt.rcParams['font.sans-serif']=['SIMHEI']  #防止中文乱码
    #f = plt.figure(figsize=(5, 4), tight_layout=True)
    get_data(path)
    chart(*get_data(path))
'''
    # 将绘制的图形显示到tkinter:创建属于root的canvas画布,并将图f置于画布上
    canvas = FigureCanvasTkAgg(f, master=root)
    canvas.draw()  # 注意show方法已经过时了,这里改用draw
    canvas.get_tk_widget().pack(side=TOP,  # 上对齐
                                fill=BOTH,  # 填充方式
                                expand=YES)  # 随窗口大小调整而调整

    # matplotlib的导航工具栏显示上来(默认是不会显示它的)
    toolbar = NavigationToolbar2Tk(canvas, root)
    toolbar.update()
    canvas._tkcanvas.pack(side=TOP,  # get_tk_widget()得到的就是_tkcanvas
                          fill=BOTH,
                          expand=YES)
'''

button_5 = Button(root, text='Excel分析', command=excel_, width=11)
button_5.place(x=400, y=418)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-1 14:28:08 | 显示全部楼层
疾风怪盗 发表于 2020-9-1 14:19
你把代码放上来看看吧

用rsj0315的代码,窗口界面不变形的

数据我发在上面的压缩包里面了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-1 14:37:56 | 显示全部楼层
差不多先生air 发表于 2020-9-1 14:28
数据我发在上面的压缩包里面了

试过了,窗口界面没变形,就是用的你的代码和数据,能正常出图
你的代码少了一句没贴,root.mainloop()
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-1 14:44:04 | 显示全部楼层
疾风怪盗 发表于 2020-9-1 14:37
试过了,窗口界面没变形,就是用的你的代码和数据,能正常出图
你的代码少了一句没贴,root.mainloop()

为什么在我的电脑上面会出现变形呀,可以明显看见界面收缩了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-1 14:45:59 | 显示全部楼层
差不多先生air 发表于 2020-9-1 14:44
为什么在我的电脑上面会出现变形呀,可以明显看见界面收缩了

不知道,反正我这没问题,说明代码没问题,你电脑问题吧,用另外一台电脑试试看呗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-1 14:49:23 | 显示全部楼层
疾风怪盗 发表于 2020-9-1 14:45
不知道,反正我这没问题,说明代码没问题,你电脑问题吧,用另外一台电脑试试看呗

大佬  问一下,我上面注释掉的代码是将matplotlib生成图片嵌入到界面里面的,请问我怎么设置一个开关按钮,将生成的图片从界面上面删掉啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-1 14:53:34 | 显示全部楼层
疾风怪盗 发表于 2020-9-1 14:45
不知道,反正我这没问题,说明代码没问题,你电脑问题吧,用另外一台电脑试试看呗


import tkinter
#-------------设置
import matplotlib
matplotlib.use('Agg')   #该模式下绘图无法显示,plt.show()也无法作用
#-------------
from matplotlib.backends.backend_tkagg import (FigureCanvasTkAgg, NavigationToolbar2Tk)
# Implement the default Matplotlib key bindings.
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
'''
import matplotlib.pyplot as plt

import numpy as np

root = tkinter.Tk()
root.wm_title("Embedding in Tk")
# 1. 用matplotlib.figure->Figure画图---------------------------------------
#fig = Figure(figsize=(5, 4), dpi=100)
#fig_plot = fig.add_subplot(111)
#t = np.arange(0, 3, .01)
#fig_plot.plot(t, 2 * np.sin(2 * np.pi * t))
#----------------------------------------------------------------------
# 2. 用pyplot.subplots画图-------------------------------------------------
#fig, axs = plt.subplots(1, 3, figsize=(5, 4), sharey=True)
#data = {'apples': 10, 'oranges': 15, 'lemons': 5, 'limes': 20}
#names = list(data.keys())
#values = list(data.values())
#axs[0].bar(names, values)
#axs[1].scatter(names, values)
#axs[2].plot(names, values)
#fig.suptitle('Categorical Plotting')
#--------------------------------------------------------------------
# 3. 用pyplot.figure画图-------------------------------------------------
fig = plt.figure(figsize=(5, 4), tight_layout=True)
ax = fig.add_subplot(111)
ax.plot(np.arange(0, 1e6, 1000))
ax.set_ylabel('YLabel0')
ax.set_xlabel('XLabel0')
for tick in ax.get_xticklabels():
    tick.set_rotation(90)
#fig.align_labels()  # same as fig.align_xlabels(); fig.align_ylabels()

#------------------------------------
canvas = FigureCanvasTkAgg(fig, master=root)  # A tk.DrawingArea.
canvas.draw()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

#matplotlib工具条---------------------------------
#toolbar = NavigationToolbar2Tk(canvas, root)
#toolbar.update()
#canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

def on_key_press(event):
    print("you pressed {}".format(event.key))
    key_press_handler(event, canvas, toolbar)


canvas.mpl_connect("key_press_event", on_key_press)

def _quit():
    print('quit')
    root.quit()     # stops mainloop
    root.destroy()  # this is necessary on Windows to prevent
                    # Fatal Python Error: PyEval_RestoreThread: NULL tstate

button = tkinter.Button(master=root, text="Quit", command=_quit)
button.pack(side=tkinter.BOTTOM)

tkinter.mainloop()
# If you put root.destroy() here, it will cause an error if the window is
# closed with the window manager
'''


from tkinter import *
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
from matplotlib.backend_bases import key_press_handler
from matplotlib.figure import Figure
import openpyxl as xl
import matplotlib.pyplot as plt
from tkinter import  filedialog


root = tkinter.Tk()  # 创建tkinter的主窗口
root.title("在tkinter中使用matplotlib")

f = plt.figure(figsize=(5, 4), tight_layout=True)
#ax = f.add_subplot(111)

'''
f = Figure(figsize=(5, 4), dpi=100)
a = f.add_subplot(111)  # 添加子图:1行1列第1个

# 生成用于绘sin图的数据
x = np.arange(0, 3, 0.01)
y = np.sin(2 * np.pi * x)

# 在前面得到的子图上绘图
a.plot(x, y)
'''

def _start():
    def get_data(path):
        wb = xl.load_workbook(path,data_only=True)
        ws = wb.active

        hezha_lst = []
        A_lst = []
        B_lst = []
        C_lst = []

        for row in ws.iter_rows(min_row=2,max_row=4,min_col=1,max_col=4):
            # print(row[0].value,row[4].value)
            hezha_lst.append(row[0].value)
            A_lst.append(row[1].value)
            B_lst.append(row[2].value)
            C_lst.append(row[3].value)
            
        return hezha_lst,A_lst,B_lst,C_lst

    def chart(x,y1,y2,y3):
        plt.plot(x,y1,label='A相')
        plt.scatter(x,y1,color='r')
        plt.plot(x,y2,label='B相')
        plt.scatter(x,y2,color='g')
        plt.plot(x,y3,label='C相')
        plt.scatter(x,y3,color='b')
        plt.title('合闸数据分析')
        #plt.legend()
        #plt.savefig('test.png')
        #plt.show()


    path = filedialog.askopenfilename(title='选择Excel文件路径', filetypes=[('*.xlsx', '.xlsx')])
    plt.rcParams['font.sans-serif']=['SIMHEI']  #防止中文乱码
   
    get_data(path)
    chart(*get_data(path))

   
    # 将绘制的图形显示到tkinter:创建属于root的canvas画布,并将图f置于画布上
    canvas = FigureCanvasTkAgg(f, master=root)
    canvas.draw()  # 注意show方法已经过时了,这里改用draw
    canvas.get_tk_widget().place(height=300,width=300,x=150, y=20)

    # matplotlib的导航工具栏显示上来(默认是不会显示它的)
    toolbar = NavigationToolbar2Tk(canvas, root)
    toolbar.update()
    canvas._tkcanvas.place(height=300,width=300)

'''
def on_key_event(event):
    """键盘事件处理"""
    print("你按了%s" % event.key)
    key_press_handler(event, canvas, toolbar)


# 绑定上面定义的键盘事件处理函数
canvas.mpl_connect('key_press_event', on_key_event)
'''  

def _quit():
    """点击退出按钮时调用这个函数"""
    root.quit()  # 结束主循环
    root.destroy()  # 销毁窗口

def qingchu():
    plt.close('all')

root.geometry('595x560')  # 设置窗口大小
root.resizable(width=False, height=False)  # 禁止拉伸根窗口

'''
scrollbar = Scrollbar(root)  # 设置滚动条

text = Text(root,font=('宋体', 15),height=18, width=57, bg='#cbeaf8', undo=True,yscrollcommand=scrollbar.set)
text.grid(columnspan=3)

scrollbar.config(command=text.yview)
scrollbar.grid(row=0, column=3, stick=E + N + S)
'''

# 创建一个按钮,并把上面那个函数绑定过来
button_1 = tkinter.Button(master=root, text="退出", command=_quit,width=11)
# 按钮放在下边
button_1.place(x=300, y=373)

# 创建一个按钮,并把上面那个函数绑定过来
button_2 = tkinter.Button(master=root, text="启动", command=_start,width=11)
# 按钮放在下边
button_2.place(x=460, y=373)

button_3 = tkinter.Button(master=root, text="清除画布", command=qingchu)
# 按钮放在下边
button_3.place(x=150, y=373)

# 主循环
mainloop()


这是我测试这个的代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-1 14:53:59 | 显示全部楼层
差不多先生air 发表于 2020-9-1 14:49
大佬  问一下,我上面注释掉的代码是将matplotlib生成图片嵌入到界面里面的,请问我怎么设置一个开关按钮 ...

我不是大佬,就学了三个月的初学者
我没学过TK,也没做过。。。。。。。。只会找错,你要问我怎么做,不知道额。。。。。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-1 14:54:56 | 显示全部楼层
疾风怪盗 发表于 2020-9-1 14:53
我不是大佬,就学了三个月的初学者
我没学过TK,也没做过。。。。。。。。只会找错,你要问我怎么做,不 ...

没事没事  还是很感谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-1 15:45:47 | 显示全部楼层    本楼为最佳答案   
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from tkinter import *

class testme:
    def __init__(self,frame1):
        self.frame1=frame1
        self.button=Button(self.frame1,text="DRAWME",command=self.plot)
        self.button1=Button(self.frame1,text="CLEARME",command=self.clearme)
        self.button.pack()
        self.button1.pack()

    def plot(self):
        f=Figure(figsize=(5,1))
        aplt=f.add_subplot(111)
        aplt.plot([1,2,3,4])
        self.wierdobject = FigureCanvasTkAgg(f, master=self.frame1)
        self.wierdobject.get_tk_widget().pack()
        self.wierdobject.draw()

    def clearme(self):
       self.wierdobject.get_tk_widget().pack_forget()

root=Tk()
aframe=Frame(root)
testme(aframe)
aframe.pack()  #packs a frame which given testme packs frame 1 in testme
root.mainloop()

网上找到这样一段代码,应该是你要实现的功能,看着改改试试呗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-1 16:05:42 | 显示全部楼层
疾风怪盗 发表于 2020-9-1 15:45
网上找到这样一段代码,应该是你要实现的功能,看着改改试试呗

谢谢了,我调试好了,能方便问一下一般都是在哪里找解决方法吗
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-1 16:16:43 | 显示全部楼层
差不多先生air 发表于 2020-9-1 16:05
谢谢了,我调试好了,能方便问一下一般都是在哪里找解决方法吗

就是度娘,找啊找,每个链接打开看一下。。。。。。。。。。
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg,NavigationToolbar2Tk
from matplotlib.figure import Figure
import matplotlib.pyplot as plt
import openpyxl as xl
from tkinter import *
from tkinter import  filedialog

class testme:
    def __init__(self,frame1):
        self.frame1=frame1
        self.button=Button(self.frame1,text="DRAWME",command=self.plot)
        self.button1=Button(self.frame1,text="CLEARME",command=self.clearme)
        self.button.pack()
        self.button1.pack()

    def plot(self):
        f=Figure()

        def get_data(path):
            wb = xl.load_workbook(path, data_only=True)
            ws = wb.active

            hezha_lst = []
            A_lst = []
            B_lst = []
            C_lst = []

            for row in ws.iter_rows(min_row=2, max_row=4, min_col=1, max_col=4):
                # print(row[0].value,row[4].value)
                hezha_lst.append(row[0].value)
                A_lst.append(row[1].value)
                B_lst.append(row[2].value)
                C_lst.append(row[3].value)

            return hezha_lst, A_lst, B_lst, C_lst

        def chart(x, y1, y2, y3):
            ax=f.add_subplot(111)
            ax.plot(x, y1, label='A相')
            ax.scatter(x, y1, color='r')
            ax.plot(x, y2, label='B相')
            ax.scatter(x, y2, color='g')
            ax.plot(x, y3, label='C相')
            ax.scatter(x, y3, color='b')
            ax.set_title('合闸数据分析')
            ax.legend()
            #plt.show()

        path = filedialog.askopenfilename(title='选择Excel文件路径', filetypes=[('*.xlsx', '.xlsx')])
        plt.rcParams['font.sans-serif'] = ['SIMHEI']  # 防止中文乱码
        # f = plt.figure(figsize=(5, 4), tight_layout=True)
        get_data(path)
        chart(*get_data(path))

        self.wierdobject = FigureCanvasTkAgg(f, master=self.frame1)
        self.wierdobject.get_tk_widget().pack(side=TOP,  # 上对齐
                                fill=BOTH,  # 填充方式
                                expand=YES)  # 随窗口大小调整而调整
        self.wierdobject.draw()
        '''
        # matplotlib的导航工具栏显示上来(默认是不会显示它的)
        toolbar = NavigationToolbar2Tk(self.wierdobject, root)
        toolbar.update()
        self.wierdobject._tkcanvas.pack(side=TOP,  # get_tk_widget()得到的就是_tkcanvas
                              fill=BOTH,
                              expand=YES)
        '''
    def clearme(self):
       self.wierdobject.get_tk_widget().pack_forget()
       #self.wierdobject._tkcanvas.pack_forget()

root=Tk()
aframe=Frame(root)
testme(aframe)
aframe.pack()  #packs a frame which given testme packs frame 1 in testme
root.mainloop()
我也改了一下,能达到你的要求,但是就是工具栏好像不能清楚,会重复好几个,不知道怎么弄,你这边调试好了就行,我也不会TK
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-1 16:25:48 | 显示全部楼层
疾风怪盗 发表于 2020-9-1 16:16
就是度娘,找啊找,每个链接打开看一下。。。。。。。。。。

我也改了一下,能达到你的要求,但是就是 ...

我也是刚学了一个多星期,非常谢谢你帮忙了许多
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-18 20:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表