鱼C论坛

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

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

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

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

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

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

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


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


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

  4. class testme:
  5.     def __init__(self,frame1):
  6.         self.frame1=frame1
  7.         self.button=Button(self.frame1,text="DRAWME",command=self.plot)
  8.         self.button1=Button(self.frame1,text="CLEARME",command=self.clearme)
  9.         self.button.pack()
  10.         self.button1.pack()

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

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

  20. root=Tk()
  21. aframe=Frame(root)
  22. testme(aframe)
  23. aframe.pack()  #packs a frame which given testme packs frame 1 in testme
  24. root.mainloop()
复制代码


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

机械特性数据测试.zip

6.13 KB, 下载次数: 1

小甲鱼最新课程 -> https://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”
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

你用源代码编译的时候,调用matplotlib函数的时候,界面会变形吗?
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

你把代码放上来看看吧

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

你用他的代码也可以试一下,看看会不会有问题
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

  5. root = Tk()

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

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

  12.         hezha_lst = []
  13.         A_lst = []
  14.         B_lst = []
  15.         C_lst = []

  16.         for row in ws.iter_rows(min_row=2,max_row=4,min_col=1,max_col=4):
  17.             # print(row[0].value,row[4].value)
  18.             hezha_lst.append(row[0].value)
  19.             A_lst.append(row[1].value)
  20.             B_lst.append(row[2].value)
  21.             C_lst.append(row[3].value)
  22.             
  23.         return hezha_lst,A_lst,B_lst,C_lst

  24.     def chart(x,y1,y2,y3):
  25.         plt.plot(x,y1,label='A相')
  26.         plt.scatter(x,y1,color='r')
  27.         plt.plot(x,y2,label='B相')
  28.         plt.scatter(x,y2,color='g')
  29.         plt.plot(x,y3,label='C相')
  30.         plt.scatter(x,y3,color='b')
  31.         plt.title('合闸数据分析')
  32.         plt.legend()
  33.         plt.show()

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

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

  53. button_5 = Button(root, text='Excel分析', command=excel_, width=11)
  54. button_5.place(x=400, y=418)
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

数据我发在上面的压缩包里面了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

试过了,窗口界面没变形,就是用的你的代码和数据,能正常出图
你的代码少了一句没贴,root.mainloop()
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

为什么在我的电脑上面会出现变形呀,可以明显看见界面收缩了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

不知道,反正我这没问题,说明代码没问题,你电脑问题吧,用另外一台电脑试试看呗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

大佬  问一下,我上面注释掉的代码是将matplotlib生成图片嵌入到界面里面的,请问我怎么设置一个开关按钮,将生成的图片从界面上面删掉啊
小甲鱼最新课程 -> https://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()


这是我测试这个的代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

我不是大佬,就学了三个月的初学者
我没学过TK,也没做过。。。。。。。。只会找错,你要问我怎么做,不知道额。。。。。。。。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

没事没事  还是很感谢
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

  4. class testme:
  5.     def __init__(self,frame1):
  6.         self.frame1=frame1
  7.         self.button=Button(self.frame1,text="DRAWME",command=self.plot)
  8.         self.button1=Button(self.frame1,text="CLEARME",command=self.clearme)
  9.         self.button.pack()
  10.         self.button1.pack()

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

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

  20. root=Tk()
  21. aframe=Frame(root)
  22. testme(aframe)
  23. aframe.pack()  #packs a frame which given testme packs frame 1 in testme
  24. root.mainloop()
复制代码


网上找到这样一段代码,应该是你要实现的功能,看着改改试试呗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

谢谢了,我调试好了,能方便问一下一般都是在哪里找解决方法吗
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

  7. class testme:
  8.     def __init__(self,frame1):
  9.         self.frame1=frame1
  10.         self.button=Button(self.frame1,text="DRAWME",command=self.plot)
  11.         self.button1=Button(self.frame1,text="CLEARME",command=self.clearme)
  12.         self.button.pack()
  13.         self.button1.pack()

  14.     def plot(self):
  15.         f=Figure()

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

  19.             hezha_lst = []
  20.             A_lst = []
  21.             B_lst = []
  22.             C_lst = []

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

  29.             return hezha_lst, A_lst, B_lst, C_lst

  30.         def chart(x, y1, y2, y3):
  31.             ax=f.add_subplot(111)
  32.             ax.plot(x, y1, label='A相')
  33.             ax.scatter(x, y1, color='r')
  34.             ax.plot(x, y2, label='B相')
  35.             ax.scatter(x, y2, color='g')
  36.             ax.plot(x, y3, label='C相')
  37.             ax.scatter(x, y3, color='b')
  38.             ax.set_title('合闸数据分析')
  39.             ax.legend()
  40.             #plt.show()

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

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

  62. root=Tk()
  63. aframe=Frame(root)
  64. testme(aframe)
  65. aframe.pack()  #packs a frame which given testme packs frame 1 in testme
  66. root.mainloop()
复制代码

我也改了一下,能达到你的要求,但是就是工具栏好像不能清楚,会重复好几个,不知道怎么弄,你这边调试好了就行,我也不会TK
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

我也是刚学了一个多星期,非常谢谢你帮忙了许多
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-6-26 14:16

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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