Tkinter嵌入matplotlib直方图报FigureCanvasTkAgg无show属性问题
报错原因及解决方案
两个报错的直接诱因
- 第一个
AttributeError: 'FigureCanvasTkAgg' object has no attribute 'show'报错:由matplotlib版本差异导致。3.1及以上版本的FigureCanvasTkAgg已经移除了show()方法,替换为draw()方法,你参考的旧案例使用的是更低版本的matplotlib,所以可以正常运行。 - 第二个
'NoneType' object has no attribute 'get_tk_widget'报错:由链式调用的写法错误导致。show()和draw()都是无返回值的方法,执行后返回None,你直接把方法调用结果赋值给canvas变量,相当于canvas = None,后续调用get_tk_widget()自然会报错。
额外隐藏问题
你当前代码还有两个会导致最终无法正常显示图表的问题:
- 绘图对象不匹配:你用
plt.hist()是在matplotlib默认的全局画布上绘图,但是后续传入FigureCanvasTkAgg的是你新创建的空Figure对象f,两者没有关联,就算前面报错修复了也只会显示空白画布。 - 字段不存在:你提供的测试数据里没有
name字段,直接取df["name"]会触发KeyError,需要替换为实际存在的字段,比如visitor_source、ts等。
修正后代码
from tkinter import * import json import pandas as pd from matplotlib.figure import Figure from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg # 主窗口初始化(原代码漏了主窗口实例化,此处补充) window = Tk() window.geometry("300x200") window.title("主窗口") def openWindowForT2(): with open('Data.json', 'r') as file1: df= pd.read_json(file1, lines=True) windowforT2 = Toplevel(window) windowforT2.title("New Window") windowforT2.geometry("600x600") frame = Frame(windowforT2) frame.place(relx=0.5, rely=0.1,relwidth=0.75 ,relheight=0.1,anchor='n') nam = Entry(frame,font=40) nam.place(relwidth=0.65, relheight=1) button1 = Button(frame, text= "Get graph") button1.place(relx=0.7,relwidth=0.3,relheight=1) # 修正1:在自定义的Figure对象上绘图,不使用plt全局绘图 f = Figure(figsize=(5,4), dpi=100) # 尺寸适配窗口,不要设置过大 ax = f.add_subplot(111) # 修正2:替换为实际存在的字段,此处示例统计visitor_source的分布 x1 = df["visitor_source"] ax.hist(x1, density=True, bins=30) ax.set_ylabel("time") ax.set_xlabel("val") # 修正3:先实例化画布对象存入canvas变量,再调用draw方法 canvas = FigureCanvasTkAgg(f, master = windowforT2) canvas.draw() canvas.get_tk_widget().pack(side= TOP, fill=BOTH,expand=True) # 补充打开子窗口的测试按钮 open_btn = Button(window, text="打开统计窗口", command=openWindowForT2) open_btn.pack(pady=50) window.mainloop()
内容的提问来源于stack exchange,提问作者newbieperson
相关产品推荐
相关产品推荐

