Title: FigureCanvasTkAgg memory leak · Issue #24820 · matplotlib/matplotlib · GitHub
Open Graph Title: FigureCanvasTkAgg memory leak · Issue #24820 · matplotlib/matplotlib
X Title: FigureCanvasTkAgg memory leak · Issue #24820 · matplotlib/matplotlib
Description: Bug summary I'm trying to update a plot in tkinter by destroying the frame where the FigureCanvasTkAgg tk widget is packed and creating another instance of FigureCanvasTkAgg, but the memory of the script only goes up after repeating the ...
Open Graph Description: Bug summary I'm trying to update a plot in tkinter by destroying the frame where the FigureCanvasTkAgg tk widget is packed and creating another instance of FigureCanvasTkAgg, but the memory of the ...
X Description: Bug summary I'm trying to update a plot in tkinter by destroying the frame where the FigureCanvasTkAgg tk widget is packed and creating another instance of FigureCanvasTkAgg, but the memory of ...
Opengraph URL: https://github.com/matplotlib/matplotlib/issues/24820
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"FigureCanvasTkAgg memory leak","articleBody":"### Bug summary\n\nI'm trying to update a plot in tkinter by destroying the frame where the FigureCanvasTkAgg tk widget is packed and creating another instance of FigureCanvasTkAgg, but the memory of the script only goes up after repeating the process several times.\n\n### Code for reproduction\n\n```python\nimport tkinter as tk\r\nfrom tkinter import ttk\r\nfrom matplotlib.backends.backend_tkagg import FigureCanvasTkAgg\r\nfrom matplotlib.figure import Figure\r\nimport numpy as np\r\n\r\nclass Main_Program(tk.Tk):\r\n def __init__(self, *args, **kwargs):\r\n tk.Tk.__init__(self, *args, **kwargs)\r\n \r\n self.geometry(\"500x500\")\r\n \r\n # ---------------------------------------- TOP FRAME (Button)\r\n \r\n self.top_frame = tk.Frame(self) \r\n ttk.Button(self.top_frame,text=\"Update graph\",command=self.update_graph).pack()\r\n self.top_frame.pack()\r\n \r\n # ---------------------------------------- BOTTOM FRAME (Graph)\r\n \r\n self.bottom_frame = tk.Frame(self) \r\n \r\n DisplayGraph(self.bottom_frame,\r\n x_limit= (-10, 10) ,\r\n delta_x= 0.1 ,\r\n y_input= \"2*x+2\" )\r\n \r\n self.bottom_frame.pack() \r\n \r\n \r\n def update_graph(self):\r\n \r\n # ----------------------------- CLEAR\r\n \r\n for widget in self.bottom_frame.winfo_children():\r\n widget.destroy()\r\n \r\n # ----------------------------- DISPLAY NEW GRAPH\r\n \r\n DisplayGraph(self.bottom_frame,\r\n x_limit= (-10, 10) ,\r\n delta_x= 0.1 ,\r\n y_input= \"2*x+2\" )\r\n \r\nclass DisplayGraph:\r\n def __init__(self,passed_frame,\r\n x_limit=(), # TUPLE (-10,10)\r\n delta_x=0.0, # FLOAT 0.1\r\n y_input='', # STRING 2*x+2\r\n figsize_x=6,\r\n figsize_y=5):\r\n\r\n self.x_limit = x_limit\r\n self.delta_x = delta_x\r\n self.y_input = y_input\r\n \r\n # ---------------------------------------------------------- CREATE FIGURE AND SUBPLOT\r\n\r\n self.fig = Figure(figsize=(figsize_x,figsize_y),dpi=100)\r\n self.ax = self.fig.add_subplot(111)\r\n self.ax.grid()\r\n \r\n # ---------------------------------------------------------- PLOT\r\n \r\n self.plot_input()\r\n\r\n # ---------------------------------------------------------- PACK AND DRAW\r\n\r\n self.canvas_frame = tk.Frame(passed_frame,bg=\"black\")\r\n self.canvas_mat = FigureCanvasTkAgg(self.fig, master=self.canvas_frame)\r\n \r\n self.canvas_mat.get_tk_widget().pack(anchor=\"center\", expand=True,padx=2,pady=2)\r\n self.canvas_frame.pack(side=tk.LEFT,anchor=\"center\", expand=True)\r\n \r\n self.canvas_mat.draw()\r\n \r\n # ----------------------------------------------------------\r\n \r\n def plot_input(self):\r\n\r\n x = np.arange(self.x_limit[0],self.x_limit[1],self.delta_x)\r\n y = eval(self.y_input)\r\n\r\n self.ax.plot(x,y)\r\n\r\nApp = Main_Program()\r\nApp.mainloop()\n```\n\n\n### Actual outcome\n\nMemory after running the script for the first time\r\n\r\n\r\n\r\nMemory after clicking the button 20 times:\r\n\r\n\r\nI've seen that some of the memory is freed after a while but not immediately after updating the frame.\n\n### Expected outcome\n\nI would expect that destroying the frame where the FigureCanvasTkAgg widget is located would allow me to create another instance of FigureCanvasTkAgg without increasing the memory (or at least too much).\n\n### Additional information\n\nI've seen posts as far back as 13 years ago reporting the issue in different places, but I have not been able to find a way to solve it. I know that you can create only one instance of the FigureCanvasTkAgg object and clear/plot each time, but I'm working on a project that involves several figures at the same time and closing the tkinter toplevel window does not seem to clear the memory.\n\n### Operating system\n\nWindows\n\n### Matplotlib Version\n\n3.6.2\n\n### Matplotlib Backend\n\nTkAgg\n\n### Python version\n\n3.11.0\n\n### Jupyter version\n\n_No response_\n\n### Installation\n\npip","author":{"url":"https://github.com/cenfra-git","@type":"Person","name":"cenfra-git"},"datePublished":"2022-12-27T00:17:56.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":4},"url":"https://github.com/24820/matplotlib/issues/24820"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:8367caad-9ee4-9392-87c2-0aee5067ed25 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 972E:328753:2428DE5:325B1C8:6A50BCC3 |
| html-safe-nonce | 266e9e283eb0ee1e1cf596dbd981bc23747a72d3f2e18ad0b85c72b276c2edef |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI5NzJFOjMyODc1MzoyNDI4REU1OjMyNUIxQzg6NkE1MEJDQzMiLCJ2aXNpdG9yX2lkIjoiMjc0NDAyNzgwMjMwNzE4MTc2MyIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 4c2cd255b729535ca68e665ac12ff104c86c23c6154a250c48ce625f6575a051 |
| hovercard-subject-tag | issue:1511322346 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/matplotlib/matplotlib/24820/issue_layout |
| twitter:image | https://opengraph.githubassets.com/8bdd57bd4c3d41709a22e083e09503f3c957735ebb4734b4b6e01ba7d8f53210/matplotlib/matplotlib/issues/24820 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/8bdd57bd4c3d41709a22e083e09503f3c957735ebb4734b4b6e01ba7d8f53210/matplotlib/matplotlib/issues/24820 |
| og:image:alt | Bug summary I'm trying to update a plot in tkinter by destroying the frame where the FigureCanvasTkAgg tk widget is packed and creating another instance of FigureCanvasTkAgg, but the memory of the ... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | cenfra-git |
| hostname | github.com |
| expected-hostname | github.com |
| None | 72b13e0e8d0319acdd27a145cfe73f4f06c791713d0ac4690e41fb68ad28cac0 |
| turbo-cache-control | no-preview |
| go-import | github.com/matplotlib/matplotlib git https://github.com/matplotlib/matplotlib.git |
| octolytics-dimension-user_id | 215947 |
| octolytics-dimension-user_login | matplotlib |
| octolytics-dimension-repository_id | 1385122 |
| octolytics-dimension-repository_nwo | matplotlib/matplotlib |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1385122 |
| octolytics-dimension-repository_network_root_nwo | matplotlib/matplotlib |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 08e79d53fc070870d5b168356afebb1e286a2ffe |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width