matplotlib 弹出窗口中的错误(AttributeError: 'NoneType' 对象没有属性 'set_canvas') [英] Error in matplotlib popup window (AttributeError: 'NoneType' object has no attribute 'set_canvas')

查看:53
本文介绍了matplotlib 弹出窗口中的错误(AttributeError: 'NoneType' 对象没有属性 'set_canvas')的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在弹出窗口中绘制图形.它弹出.但是有一个错误.

I tried to plot the graph in pop up window. It pops up. But there is an error.

import tkinter as tk
window = tk.Tk()
window.configure(background='white')


label_1 = tk.Label(window, text="Conpyright 123456789123456798", anchor=tk.S)
label_1.pack()

ws = window.winfo_screenwidth()
hs = window.winfo_screenheight()
w = 980  # width for the Tk root
h = 600  # height for the Tk root
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)



window.geometry('%dx%d+%d+%d' % (w, h, x, y))
canvas = tk.Canvas(window, bg="white", width=980, height=580, highlightthickness=0)
canvas.pack()
canvas_scroll = tk.Scrollbar(canvas, command=canvas.yview)
canvas_scroll.place(relx=1, rely=0, relheight=1, anchor=tk.NE)
canvas.configure(yscrollcommand=canvas_scroll.set, scrollregion=())



minw_var = tk.DoubleVar()
entry_minw_number = tk.Entry(canvas, textvariable=minw_var)
canvas.create_window(220,215, window=entry_minw_number)

maxw_var = tk.DoubleVar()
entry_maxw_number = tk.Entry(canvas, textvariable=maxw_var)
canvas.create_window(355,215, window=entry_maxw_number)


minl_var = tk.DoubleVar()
entry_minl_number = tk.Entry(canvas, textvariable=minl_var)
canvas.create_window(220,240, window=entry_minl_number)

maxl_var = tk.DoubleVar()
entry_maxl_number = tk.Entry(canvas, textvariable=maxl_var)
canvas.create_window(355,240, window=entry_maxl_number)

rect_var = tk.IntVar()
entry_rect_number = tk.Entry(canvas, textvariable=rect_var)
canvas.create_window(290,270, window=entry_rect_number)

这是 matplotlib 的部分

And this is the part for matplotlib

def plot_sheet(self):
    fig,ax = plt.subplots(1)
    ax.set_xlim([0, self.W]) 
    ax.set_ylim([0, self.L]) 
    recs = []
    for i in range(len(self.rect_list)):
        if self.rect_rotate[i]:
            ax.add_patch(patches.Rectangle((self.rect_pos[i][0], self.rect_pos[i][1]), self.rect_list[i].l, self.rect_list[i].w,linewidth=3,edgecolor='r'))
        else:
            ax.add_patch(patches.Rectangle((self.rect_pos[i][0], self.rect_pos[i][1]), self.rect_list[i].w, self.rect_list[i].l,linewidth=3,edgecolor='r'))
    #plt.show()
    return fig
def plot_sheets(self):
    for i in range(len(self.sheets)):
        self.sheets[i].plot_sheet()

def cal_culate1():

    fig = packing_options[best_index].plot_sheets()

    dataPlot = FigureCanvasTkAgg(fig, master = window)
    dataPlot.show()
    dataPlot.get_tk_widget().pack(side='top', fill='both', expand=1)

window.mainloop()

我写了 dataPlot = FigureCanvasTkAgg(fig, master = window).master = window 有错误.

I wrote dataPlot = FigureCanvasTkAgg(fig, master = window). There is an error in master = window.

文件",第 687 行,在 cal_culate1 中dataPlot = FigureCanvasTkAgg(fig, master = window)

File "", line 687, in cal_culate1 dataPlot = FigureCanvasTkAgg(fig, master = window)

文件C:\Users\sel\Anaconda3\lib\site-packages\matplotlib\backends_backend_tk.py",第 204 行,initsuper(FigureCanvasTk, self).init(figure)

File "C:\Users\sel\Anaconda3\lib\site-packages\matplotlib\backends_backend_tk.py", line 204, in init super(FigureCanvasTk, self).init(figure)

文件C:\Users\sel\Anaconda3\lib\site-packages\matplotlib\backend_bases.py",第 1618 行,init图.set_canvas(self)

File "C:\Users\sel\Anaconda3\lib\site-packages\matplotlib\backend_bases.py", line 1618, in init figure.set_canvas(self)

AttributeError: 'NoneType' 对象没有属性 'set_canvas'

AttributeError: 'NoneType' object has no attribute 'set_canvas'

那里应该写什么?

推荐答案

我做了一个最小的工作示例来展示如何做到这一点.

I made minimal working example which shows how do this.

它需要更改您的代码,但我不知道您的代码中有什么,而且您没有创建最小的工作示例.

it will need changes for your code but I don't know what you have in code and you didn't create minimal working example.

它使用 plot_sheetgenerate_all_figures(在您的代码中将是 plot_sheetss)创建三个图形(没有 s)并保留在列表中.

It creates three figures in generate_all_figures (in your code it will be plot_sheets with s) using plot_sheet (without s) and keep on list.

window 显示此列表中的第一个图形.

window display first figure from this list.

Buttons 删除带有图形的画布,并使用列表中的下一个/上一个图形创建新画布.

Buttons remove canvas with figure and create new canvas with next/previous figure from list.

我使用 grid() 而不是 pack() 因为这样我可以轻松地将新画布放在同一个地方.

I use grid() instead of pack() because this way I can easily put new canvas in the same place.

import tkinter as tk
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

class MyClass():

    def __init__(self):

        self.sheets = [[1,2,3], [3,1,2], [1,5,1]]
        self.W = 2
        self.L = 5
        self.all_figures = []

    def plot_sheet(self, data):
        """plot single figure"""

        fig, ax = plt.subplots(1)

        ax.set_xlim([0, self.W]) 
        ax.set_ylim([0, self.L])

        ax.plot(data)

        return fig

    def generate_all_figures(self):
        """create all figures and keep them on list"""

        for data in self.sheets:
            fig = self.plot_sheet(data)
            self.all_figures.append(fig)

def show_figure(number):
    global dataPlot

    # remove old canvas
    if dataPlot is not None: # at start there is no canvas to destroy
        dataPlot.get_tk_widget().destroy()

    # get figure from list
    one_figure = my_class.all_figures[number]

    # display canvas with figuere
    dataPlot = FigureCanvasTkAgg(one_figure, master=window)
    dataPlot.draw()
    dataPlot.get_tk_widget().grid(row=0, column=0)

def on_prev():
    global selected_figure

    # get number of previous figure
    selected_figure -= 1
    if selected_figure < 0:
        selected_figure = len(my_class.all_figures)-1

    show_figure(selected_figure)

def on_next():
    global selected_figure

    # get number of next figure
    selected_figure += 1
    if selected_figure > len(my_class.all_figures)-1:
        selected_figure = 0

    show_figure(selected_figure)

# --- main ---

my_class = MyClass()
my_class.generate_all_figures()

window = tk.Tk()
window.rowconfigure(0, minsize=500)    # minimal height
window.columnconfigure(0, minsize=700) # minimal width

# display first figure    
selected_figure = 0
dataPlot = None # default value for `show_figure`
show_figure(selected_figure)

# add buttons to change figures
frame = tk.Frame(window)
frame.grid(row=1, column=0)

b1 = tk.Button(frame, text="<<", command=on_prev)
b1.grid(row=0, column=0)

b2 = tk.Button(frame, text=">>", command=on_next)
b2.grid(row=0, column=1)

window.mainloop()

<小时>

可能可以在不替换画布的情况下通过替换绘图中的数据来完成 (fig.data ???, ax.data ??? 我不记得了)


Probably it could be done without replacing canvas but by replacing data in plot (fig.data ???, ax.data ??? I don't remember)

这篇关于matplotlib 弹出窗口中的错误(AttributeError: 'NoneType' 对象没有属性 'set_canvas')的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆