New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Bug (?) - matplotlib window grows with repeated pressing of "plot" button #5030
Comments
IMO, it is cause by the figure maybe also deleted in function Here, just clear the content of figure and not to delete it. from random import randint
import PySimpleGUI as sg
import numpy as np
"""
Embedding the Matplotlib toolbar into your application
"""
# ------------------------------- This is to include a matplotlib figure in a Tkinter canvas
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk
def draw_figure_w_toolbar(canvas, fig, canvas_toolbar):
figure_canvas_agg = FigureCanvasTkAgg(fig, master=canvas)
figure_canvas_agg.draw()
toolbar = Toolbar(figure_canvas_agg, canvas_toolbar)
toolbar.update()
figure_canvas_agg.get_tk_widget().pack(side='right', fill='both', expand=1)
return figure_canvas_agg, toolbar
def draw(figure_canvas_agg, toolbar):
figure_canvas_agg.draw()
toolbar.update()
class Toolbar(NavigationToolbar2Tk):
def __init__(self, *args, **kwargs):
super(Toolbar, self).__init__(*args, **kwargs)
# ------------------------------- you have to play with this size
fig = plt.figure(num=1)
DPI = fig.dpi
fig.set_size_inches(400 * 2 / float(DPI), 400 / float(DPI))
# -------------------------------
# ------------------------------- PySimpleGUI CODE
sg.set_options(scaling=DPI / 72)
layout = [
[sg.T('Graph: y=sin(x)')],
[sg.B('Plot'), sg.B('Exit')],
[sg.T('Controls:')],
[sg.Sizer(v_pixels=60), sg.Canvas(key='controls_cv')],
[sg.T('Figure:')],
[sg.Column(
layout=[
[sg.Canvas(key='fig_cv',
# it's important that you set this size
size=(400 * 2, 400),
expand_x=True,
expand_y=True,
)]
],
background_color='#DAE0E6',
pad=(0, 0),
expand_x=True,
expand_y=True,
)],
[sg.B('Alive?')]
]
window = sg.Window('Graph with controls', layout, resizable=True, finalize=True)
figure_canvas_agg, toolbar = draw_figure_w_toolbar(window['fig_cv'].TKCanvas, fig, window['controls_cv'].TKCanvas)
while True:
event, values = window.read()
print(f"{fig.get_dpi()=}")
if event in (sg.WIN_CLOSED, 'Exit'): # always, always give a way out!
break
elif event == 'Plot':
# ------------------------------- PASTE YOUR MATPLOTLIB CODE HERE
plt.clf()
delta = randint(0, 359)/np.pi
x = np.linspace(0, 2 * np.pi)
y = np.sin(x + delta)
plt.plot(x, y)
plt.title('y=sin(x)')
plt.xlabel('X')
plt.ylabel('Y')
plt.grid()
draw(figure_canvas_agg, toolbar)
window.close() |
That does fix it, and is probably a better way to do it (rather than redrawing everything. I've just found that removing the line
from the original code also fixes the problem. . Argh! and now I can't reproduce the original issue! I have changed my monitor set up, so that might be a thing... |
OK, some more playing around, and I've gotten reproducible failing and passing of the plot as per my original code. If the options set by I don't have a non-windows machine to test it on. . and now that behaviour has just changed, and and now I've disconnected and reconnect my monitors, and the absence or presence of set_options doesn't seem to matter for my test code (above), and the absence of options does matter for my real code, arg. I hate this type of bug. Something that matplotlib has done with dpi calculations has broken something, but I don't know how to even begin to write up a bug report for this... |
Removing the following line doesn't fix this issue in my WIN10. sg.set_options(scaling=DPI / 72) Lot of conditions tested, only my previous code fix it. Destroy widget maybe not clear everything in memory and it still need to redraw everything, |
I just tried with your code, and I agree. The behaviour is different between the test code and the actual code I want to work. I'm going to leave it alone for a bit to think some more on it, and then go through my actual code to try and construct a MWE. |
Ok. A MWE is below that follows the structure of how I've written things in my actual program. I think the problem arises because of the scaling set for the screen in the display properties. With dpi_awareness turned on, screen scale set to 125%, and using matplotlib 3.5.1, the plot gets bigger with each press of the plot button. The very first printed dpi is 100, but thereafter, it is 125. If I set the screen scale to 150 or 175%, then this value goes to 150 or 175. Crucially, if the screen scale is 100%, then the plot is well-behaved. It makes no difference if the
|
Not spent much time on detail about scale, DPI and dpi_awareness. |
It's a matplotlib bug. matplotlib/matplotlib#21875 The last comment on the discourse thread is particularly telling. |
Hi rowlesmr, try to open the PySimpleGUI window with a fixed size, like that: def gui() -> None: at least on a Mac the plot will stay the same size, regardless how often "Plot" is clicked. The plot is drawn too small at first but then with the right size an instance later. Please try yourself! |
Type of Issue Bug - PySimpleGUI or matplotlib?
Clicking "Plot" with Matplotlib >= 3.5.0 will make the plot window grow. With matplotlib==3.4.3, the plot window stays the same size.
Not sure if it's a PySimpleGUI thing or not, but I haven't been able to replicate it with pure mpl code
Operating System
Windows 10
PySimpleGUI Port
tkinter
Versions
Version information can be obtained by calling
sg.main_get_debug_data()
Or you can print each version shown in ()
Python version: 3.9.4 (tags/v3.9.4:1f2e308, Apr 6 2021, 13:40:21) [MSC v.1928 64 bit (AMD64)]
port: tkinter
tkinter version: 8.6.9
PySimpleGUI version: 4.55.1
PySimpleGUI filename: C:\Users_____\Documents\GitHub\empty-venv\lib\site-packages\PySimpleGUI\PySimpleGUI.py
Matplotlib 3.5.1 and 3.4.3
Troubleshooting
These items may solve your problem. Please check those you've done by changing - [ ] to - [X]
Detailed Description
When upgrading from matplotlib 3.4.3 to 3.5.1, the behaviour of the matplotlib fig changed. (Code below is derived from one of the matplotlib demo programs and #4860). Upon repeated pressing of the "Plot" button, the plot grows to the right and down with the DPI increasing exponentially.
With matplotlib 3.4.3 the behaviour is nice. In v3.5.1, the plot grows.
I haven't been able to reproduce the behaviour in pure matplotlib code, so I was wondering if there is something going on in the background in PySimpleGUI.
Code To Duplicate
Code taken from #4860 - added print in event loop to show figure dpi
Watcha Makin?
pdCIFplotter - it's on PyPI
The text was updated successfully, but these errors were encountered: