AttributeError: 'AxesSubplot' object has no attribute 'set_canvas' - python

Good morning,
I am using tkinter with matplotlib but I am facing a problem which I will write down.
I tried many solution but nothing worked, so if you had faced the problem before or if you just know it help me please with it.
Here is my code:
import matplotlib
matplotlib.use('TkAgg')
from tkinter import *
import tkinter.simpledialog
import matplotlib.pyplot as plt
import datetime
from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
root = Tk()
root.geometry('1000x600')
middle = Frame(root)
middle.pack()
payments = {'.':0}
m = datetime.datetime.now()
def digram1():
global m
purpose = list(payments.keys())
amounts = list(payments.values())
plt.plot((purpose),(amounts))
plt.xlabel('Purpose')
plt.ylabel('Amounts')
plt.title('Outgoings for the '+ str(m.month)+'th month\n'+str(datetime.date.today()))
plt.show
fig = Figure(figsize=(5,5),dpi = 100)
ex = fig.add_subplot(111)
canvas = FigureCanvasTkAgg(ex,master=root)
canvas.show()
canvas.get_tk_widget().pack(side =tk.top,fill=tk.Both, expand = True)
digram1m = Button(middle,text='1st digram',command=digram1, height = 5,width =15 , fg ='green')
digram1m.grid(row = 5 , column = 6 ,sticky=E)
root.mainloop()
and here is the output:
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\A\Anaconda3\lib\tkinter\__init__.py", line 1699, in __call__
return self.func(*args)
File "<ipython-input-1-6c5b0c8eaae5>", line 33, in digram1
canvas = FigureCanvasTkAgg(ex,master=root)
File "C:\Users\A\Anaconda3\lib\site-packages\matplotlib\backends\backend_tkagg.py", line 173, in __init__
FigureCanvasAgg.__init__(self, figure)
File "C:\Users\A\Anaconda3\lib\site-packages\matplotlib\backend_bases.py", line 1780, in __init__
figure.set_canvas(self)
AttributeError: 'AxesSubplot' object has no attribute 'set_canvas'
I am using Jupyter notebook 5.4.0.
Thank you for your time..

Related

Playsound module raise an error for non specified files in Python

Ok so the problem is : When I click on the upload button and I don't specify a file during the askopenfilename and I leave directly with the cross an error occurs 'playsound exception' that I didn't manage to catch with try/except statement otherwise I don't know how to prevent this or fix the problem ...
code :
from tkinter import *
from tkinter import ttk
from playsound import playsound
from tkinter.filedialog import askopenfilename
root = Tk()
root.geometry('800x600')
frame1 = Frame(root,width='100',height='50',bg='black',borderwidth=1)
subframe1 = Frame(root, bg='black', width='660', height='351')
labelframe1 = Label(frame1,text='go to frame1',fg='orange',bg='black')
frame2 = Frame(root,width='100',height='50',bg='blue')
subframe2 = Frame(root, bg='blue', width='660', height='351')
labelframe2 = Label(frame2,text='go to frame2',fg='orange',bg='blue')
buttonframe1 = Button(subframe1, text="firstbutton",fg='orange')
entryframe1 = Entry(subframe1)
comboframe1 = ttk.Combobox(subframe1,values=['option1','option2' ,'option3'])
comboframe1.set('default option')
buttonframe2 = Button(subframe2, text="secondbutton",fg='orange')
entryframe2 = Entry(subframe2)
comboframe2 = ttk.Combobox(subframe2,values=['option1','option2' ,'option3'])
comboframe2.set('default option')
uploadbutton = Button(root,text='upload',fg='orange')
frame1.place(x=0,y=0)
labelframe1.place(relx=0.5,rely=0.5,anchor=CENTER)
frame2.place(x=0,y=140)
labelframe2.place(relx=0.5,rely=0.5,anchor=CENTER)
uploadbutton.place(x=0,y=240)
def change_frame1(*args):
subframe1.pack(side=RIGHT)
subframe2.pack_forget()
buttonframe1.place(x=0,y=0)
entryframe1.place(x=0,y=40)
comboframe1.place(x=0,y=80)
def change_frame2(*args):
subframe2.pack(side=RIGHT)
subframe1.pack_forget()
buttonframe2.place(x=0,y=0)
entryframe2.place(x=0,y=40)
comboframe2.place(x=0,y=80)
def upload(*args):
file = askopenfilename(filetypes= [('MP3 Files', '*.mp3')])
if file is not None:
playsound(file)
frame1.bind('<Button-1>', change_frame1)
labelframe1.bind('<Button-1>', change_frame1)
frame2.bind('<Button-1>', change_frame2)
labelframe2.bind('<Button-1>', change_frame2)
uploadbutton.bind('<Button-1>',upload)
root.mainloop()
Error :
Traceback (most recent call last):
File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.10_3.10.2288.0_x64__qbz5n2kfra8p0\lib\tkinter\__init__.py", line 1921, in __call__
return self.func(*args)
File "C:\Users\user\project\pythonproject\venv\Lib\site-packages\project.py", line 327, in <lambda>
soundbutton = Button(root, text="upload",
command = lambda : upload())
File "C:\Users\user\project\pythonproject\venv\Lib\site-packages\project.py", line 341, in upload
playsound(file)
File "C:\Users\user\project\pythonproject\venv\Lib\site-packages\playsound.py", line 35, in _playsoundWin
winCommand('open "' + sound + '" alias', alias)
File "C:\Users\user\project\pythonproject\venv\Lib\site-packages\playsound.py", line 31, in winCommand
raise PlaysoundException(exceptionMessage)
playsound.PlaysoundException:
Error 292 for command:
open "" alias playsound_0.39688356388365387
The specified command requires an alias, file, driver, or device name. Please supply one.

Python PyQtGraph - how to use setTicks?

I want to display xticks only at the locations of data points (so the xticks == wavelengths). How can I do this?
Here is my code:
from PyQt6.QtWidgets import QApplication
import pyqtgraph as pg
app = QApplication([])
wavelengths = [610, 680, 730, 760, 810, 860]
data = [239.23, 233.81, 187.27, 176.41, 172.35, 173.78]
pw = pg.plot(wavelengths, data, symbol="o")
pw.getPlotItem().getAxis('bottom').setTicks([wavelengths])
app.exec()
I tried using AxisItem.setTicks(), but it results in an error:
for val, strn in level:
TypeError: cannot unpack non-iterable int object
Traceback (most recent call last):
File "/home/jure/.local/share/virtualenvs/serial-plotting-gui-dWOiQ7Th/lib/python3.10/site-packages/pyqtgraph/graphicsItems/AxisItem.py", line 608, in paint
specs = self.generateDrawSpecs(painter)
File "/home/jure/.local/share/virtualenvs/serial-plotting-gui-dWOiQ7Th/lib/python3.10/site-packages/pyqtgraph/graphicsItems/AxisItem.py", line 936, in generateDrawSpecs
P.S. I also tried this SO answer, but it doesn't work for me
It's always bit tricky with ticks in pyqtgraph. It works with tick spacing between two ticks on the axis. On top of it, it defines levels of MajorTick, MinorTicks and so on. With setTicks You have to specify list of levels (we have only MajorTicks) and each level with list of (tick value, "tick string").
So in order for Your example to work, You have to use such a list as a parameter for setTicks method.
Here is Your modified code:
from PyQt6.QtWidgets import QApplication
import pyqtgraph as pg
app = QApplication([])
wavelengths = [610, 680, 730, 760, 810, 860]
data = [239.23, 233.81, 187.27, 176.41, 172.35, 173.78]
pw = pg.plot(wavelengths, data, symbol="o")
pw.getPlotItem().getAxis('bottom').setTicks([[(wavelength, str(wavelength)) for wavelength in wavelengths]])
app.exec()

Random image looping in tkinter

I'm trying to loop random images from a folder. So far, I can loop the images but everytime I try to use random.choice, I'm getting an error. Below is my code without random imported
import tkinter as tk
import glob
root = tk.Tk()
from PIL import ImageTk, Image
root.geometry('600x600')
pics = glob.glob("./imgs/*.png")
photos = [random.choice(tk.PhotoImage(file=x)) for x in pics]
label = tk.Label(root)
label.photos = photos
label.counter = 0
def changeimage():
label['image'] = label.photos[label.counter%len(label.photos)]
label.after(8000, changeimage)
label.counter += 1
label.pack(padx=10, pady=10)
changeimage()
root.mainloop()
Error
Traceback (most recent call last):
File "/Users/ad/Documents/Python/Project_tkinter/test1.py", line 148, in <module>
photos = [random.choice(tk.PhotoImage(file=x)) for x in pics]
File "/Users/ad/Documents/Python/Project_tkinter/test1.py", line 148, in <listcomp>
photos = [random.choice(tk.PhotoImage(file=x)) for x in pics]
File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/random.py", line 288, in choice
i = self._randbelow(len(seq))
TypeError: object of type 'PhotoImage' has no len()
You have to first create list of photos and later choose single photo
list_of_photos = [tk.PhotoImage(file=x) for x in pics]
single_photo = random.choice(list_of_photos)
but if you want to loop this list then you rather need random.shuffle() to change order on the list to have files in random order.
list_of_photos = [tk.PhotoImage(file=x) for x in pics]
random.shuffle(list_of_photos)
random.shuffle() changes original list and it doesn't return new list.

Basemap scatterplot (Matplotlib) - Error can't set attribute

I have been trying to add two lists of floats to a scatterplot using the Matplotlib. I have simply created a Basemap with mostly default settings. However, whenever I attempt to run the script I get the error below.
#!/usr/bin/python
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
def main():
wmap = Basemap()
wmap.drawmapboundary(fill_color='aqua')
wmap.fillcontinents(color='coral',lake_color='aqua')
wmap.drawcoastlines()
locationData = open("locationData", "r")
lats = []
lons = []
ASN = []
company = []
fileLine = locationData.readlines()
for i in fileLine:
parsedLine = i.split(",")
lats.append(float(parsedLine[0]))
lons.append(float(parsedLine[1]))
ASN.append(parsedLine[2])
company.append(parsedLine[3])
locationData.close()
x,y = wmap(lats,lons)
wmap.scatter(x,y)
plt.show()
if(__name__ == '__main__'):
main()
I receive the error:
Traceback (most recent call last):
File "mapGen.py", line 51, in <module>
main()
File "mapGen.py", line 45, in main
wmap.scatter(lats,lons)
File "/usr/lib/python3.7/site-packages /mpl_toolkits/basemap/__init__.py", line 563, in with_transform
return plotfunc(self,x,y,*args,**kwargs)
File "/usr/lib/python3.7/site-packages/mpl_toolkits/basemap/__init__.py", line 3253, in scatter
self._restore_hold(ax)
File "/usr/lib/python3.7/site-packages/mpl_toolkits/basemap/__init__.py", line 3229, in _restore_hold
ax._hold = self._tmp_hold
AttributeError: can't set attribute
I have tried changing around the attributes to wmap.scatter() and the variables, but there error still persists and I haven't been able to find documentation on this error. Any ideas?
This specific exception is raised when the attribute you're trying to change is a property that doesn't have a setter. It seems the basemap change is needed, adding a setter would solve the issue.
But you can change wmap.scatter(x,y) to plt.scatter(x, y) to solve it.

Python tkinter ttk.Notebook widget error

I have a problem with the Notebook widget with python 3.3.2
This is the code:
gui=Tk()
gui.title("Test")
gui.geometry()
n = ttk.Notebook(gui).grid()
f1 = ttk.Frame(n)
f2 = ttk.Frame(n)
n.add(f1, text='One')
n.add(f2, text='Two')
gui.resizable(width=TRUE, height=TRUE)
mainloop()
and this is the error:
Traceback (most recent call last):
File "C:\Users\SergiX\Desktop\SergiX44's ModTool con sorgente 3.3\SergiX44's ModTool 1.6.4.py", line 179, in <module>
n.add(f1, text='One')
AttributeError: 'NoneType' object has no attribute 'add'
I don't know the reason of the error
thanks
The problem is that you're assigning the result of the grid function to n, rather than the Notebook widget itself. The grid function always returns None, so n has a value of None, thus the error.
To fix this, try replacing this line
n = ttk.Notebook(gui).grid()
with these lines
n = ttk.Notebook(gui)
n.grid()

Categories

Resources