'Matplotlib affecting tkinter window size and process behavior
I'm trying to build a GUI with tkinter that displays an image which is dynamically updated based on the inputs given (which i removed from the MRE below).
When I generate a dummy image like np.random.randint(255, size=(2000, 2000, 3), dtype=np.uint8), the GUI works as expected and when i close it with the classic close button (red cross), the process terminates as expected. However, when I use the actual function to produce the type of image I want (generate_voronoi, which loads an input image from its file name and edits it via matplotlib), the whole GUI appears smaller and when I close the window, the process in the shell appears to be still running (no prompt). This is the code for the GUI:
class Example(Frame):
def __init__(self, master):
super().__init__(master)
self._init_image_gui()
self._set_default_params()
self._update_img()
def _init_image_gui(self):
# Create an object of tkinter ImageTk
self.img = Image.open("jap.jpg").resize((300,300))
self.img = ImageTk.PhotoImage(self.img)
# Create a Label Widget to display the text or Image
self.img_label = tk.Label(image=self.img)
self.img_label.grid(column=0, row=3, columnspan=4)
def _update_img(self):
# produce image
#voronoi_img = np.random.randint(255, size=(2000, 2000, 3), dtype=np.uint8)
voronoi_img = generate_voronoi(self.input_path, self.output_path, self.n_regions, self.padding_amount, self.pad_color, self.rounding_amount)
voronoi_img = voronoi_img.astype(np.uint8)
voronoi_img = cv2.cvtColor(voronoi_img, cv2.COLOR_BGR2RGB)
new_img = Image.fromarray(voronoi_img).resize((200, 200))
new_img = ImageTk.PhotoImage(new_img)
# update the UI to show it
self.img_label.configure(image=new_img)
self.img = new_img
def _set_default_params(self):
self.input_path = "jap.jpg"
self.output_path = "jap_out.jpg"
self.n_regions = 100
self.padding_amount = 10
self.pad_color = "#000000"
self.rounding_amount = 10
def main():
root = Tk()
root.geometry("500x500")
app = Example(root)
root.mainloop()
Altough I think the problem is in setting up the ax to work with matplotlib without any frames or paddings in the output image (which I then convert to numpy array), that is called by generate_voronoi, and is this:
def setup_plot(x : int, y : int, pad_color : str):
'''Sets up matplotlib paint axes and returns it'''
_, ax = plt.subplots(figsize=(x / 100, y / 100))
ax.axis([0, x, 0, y])
ax.axis('off')
ax.set_facecolor(pad_color)
ax.add_artist(ax.patch)
ax.patch.set_zorder(-1)
# setup ax size in pixels
ax.set_position([0, 0, 1, 1])
return ax
How can I achieve the same correct behavior as with the "dummy" image generation?
TLDR
Why does my GUI shrink in size and the process doesn't terminate when I add just this matplotlib commands (without even using them)?
def _update_img(self):
plt.figure() # this causes the problem
voronoi_img = np.random.randint(255, size=(2000, 2000, 3)
Full code can be found here
Solution 1:[1]
I solved it this way:
target_df['FiscalCode'] = target_df.apply(lambda x: codicefiscale.encode(x["Surname"], x["Name"], x["Sex"], x["BirthDate"], x["BirthPlace"]), axis=1)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | user2965031 |
