-
Notifications
You must be signed in to change notification settings - Fork 654
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 Report: mplfinance >= 0.12.5a0 crashes without an error when loading an plot image in tKinter #170
Comments
@theGOTOguy First, thank you for the awesome job providing a simple, easy means to reproduce the error. Second, a work-around for mplfinance version 0.12.5 is to set
Third, perhaps you can give me your thoughts on the source of this issue, after I fill you in on what I have found. Here is some background and what I have found so far: v0.12.5 implemented kwarg Here's the thing: The line of code to close the figure, for your use-case, is here: https://github.com/matplotlib/mplfinance/blob/master/src/mplfinance/plotting.py#L658 If I change that line of code from:
to:
then the "crash" problem goes away! Your thoughts? I am beginning to suspect the issue may be in matplotlib itself, since it appears that By the way, I have also verified (with All the best. --Daniel |
I am able to reproduce this problem by modifying
|
Thanks for the quick response, and the research into the issue! I can confirm that adding Your matplotlib-only repro is so interesting that I've looked into it further. It appears that closing a single figure and closing all figures use entirely different routines in matplotlib. Using the time-honored method of Next, I tried printing the figure number found in And now here's what I don't fully understand, but it works. I did a matplotlib at HEAD has changed from my version, so I am including a code snippet from _pylab_helpers.py in matplotlib 3.2.1: @classmethod
def destroy(cls, num):
"""
Try to remove all traces of figure *num*.
In the interactive backends, this is bound to the
window "destroy" and "delete" events.
"""
if not cls.has_fignum(num):
return
manager = cls.figs[num]
manager.canvas.mpl_disconnect(manager._cidgcf)
cls._activeQue.remove(manager)
del cls.figs[num]
manager.destroy()
gc.collect(1)
@classmethod
def destroy_fig(cls, fig):
"*fig* is a Figure instance"
num = next((manager.num for manager in cls.figs.values()
if manager.canvas.figure == fig), None)
if num is not None:
cls.destroy(num)
@classmethod
def destroy_all(cls):
# this is need to ensure that gc is available in corner cases
# where modules are being torn down after install with easy_install
import gc # noqa
for manager in list(cls.figs.values()):
manager.canvas.mpl_disconnect(manager._cidgcf)
manager.destroy()
cls._activeQue = []
cls.figs.clear()
gc.collect(1) Note that in At first I thought that somehow At any rate, you're right. This is a matplotlib bug, not a mplfinance bug. I'm happy to file a bug and a PR with matplotlib (unless you want to, you did a bunch of research into the issue too!) I do have one question, though: now knowing what exactly the issue is, is it clear to you why this crash is happening in the first place, and how it's possible that nobody's noticed it before? I'd love to have that explanation be part of the issue/PR so that I could go forward a smarter person. |
Hi Ben, Sorry for taking so long to get back to you. Thanks very much for taking this investigation further and identifying that calling At any rate, I would be honored if you would file a bug issue with I am reluctant to change mplfinance to call All the best. --Daniel |
Btw, about
I have no idea. I am still relatively new myself at this matplotlib stuff, especially when it comes to "backends" and Figure managers, and things at that level. It's still a mystery to me why closing the Figure would have anything to do with your tkInter objects, since the way it looks to me from my naive standpoint, the only thing that gets passed to tkInter is the image data in the BytesIO object. I was thinking that once matplotlib writes to the BytesIO object, anything else that matplotlib does after that would be completely idependent of anything that is done with the ByteIO object later by other code. I too would love to have an explanation so that I can go forward knowing more about both matplotlib and tkInter. |
I've created a bug in matplotlib. One caveat that they do mention is that matplotlib is explicitly not thread-safe, but as far as I can tell, tKinter's Thanks for maintaining this awesome library, and for helping me hunt down this weird bug. Always a pleasure to work with another physicist! |
@theGOTOguy P.S. It seems the bug is apparent only when using matplotlib backend "TkAgg" -- now I can understand my misconception that
Apparently when using |
Yep, makes sense. I'm good to go now that I have a workaround, but still looking forward to learning why the order of closing the manager and deleting it from the list of figures matters! |
Ben, |
Describe the bug
mplfinance crashes without an error when loading images into a tKinter label.
To Reproduce
requirements.txt:
repro.py
Steps to reproduce the behavior:
First, create a new directory and create a virtualenv for testing:
virtualenv venv -p python3
source venv/bin/activate
Install the requirements.
pip install -r requirements.txt
Run the repro.
venv/bin/python repro.py
Click the "Next!" button.
After a small number of loads (usually just the first one for me), python will crash with no error reported.
Expected behavior
You should be able to click "Next!" an unlimited number of times to continue loading new simulated candlestick graphs.
Desktop (please complete the following information):
Additional context
If you roll back to mplfinance 0.12.4a0, this crash does not occur. e.g.,:
pip install mplfinance==0.12.4a0
For now, this workaround is fine for me.
The text was updated successfully, but these errors were encountered: