-
Notifications
You must be signed in to change notification settings - Fork 225
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
remove unnecessary traitlets to fix savefig and display(fig) errors #264
Conversation
these aren't used by the js side and making them traitlets may cause errors with high enough versions of matplotlib
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for opening a PR! I can make a release after this is merged.
_button = Any() | ||
_key = Any() | ||
_lastx = Any() | ||
_lasty = Any() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wondering if those are used in core Matplotlib, do you know @tacaswell?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, we use them for preventing re-entrant draws (_is_idle_drawing
and _is_saving
) and assembling the composite events that eventually propagates through our event system (because the keyboard and mouse events come in separate and we merge them).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So is it safe removing them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The canvas still has all of these attributes that it inherits from webagg. So this runs without throwing an error:
for attr in ['_lastx', '_lasty', '_button', '_key', '_is_saving', '_is_idle_drawing']:
assert hasattr(fig.canvas, attr)
so I think it is safe to remove them.
@ianhi should I update the Matplotlib requirement when making the release? |
I don't think that's necessary? I think this will only make it compatible with more versions of matplotlib rather than fewer |
Good! Thanks, I was just wondering if that was a breaking change for older Matplotlib |
Actually hang on. I may have introduced an error with mapltotlib ==3.2 |
On ---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/matplotlib/backend_bases.py in _wait_cursor_for_draw_cm(self)
2772 try:
-> 2773 self.set_cursor(cursors.WAIT)
2774 yield
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/matplotlib/backends/backend_webagg_core.py in set_cursor(self, cursor)
380 if cursor != self.cursor:
--> 381 self.canvas.send_event("cursor", cursor=cursor)
382 self.cursor = cursor
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/matplotlib/backends/backend_webagg_core.py in send_event(self, event_type, **kwargs)
345 def send_event(self, event_type, **kwargs):
--> 346 self.manager._send_event(event_type, **kwargs)
347
AttributeError: 'NoneType' object has no attribute '_send_event'
During handling of the above exception, another exception occurred:
AttributeError Traceback (most recent call last)
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/IPython/core/formatters.py in __call__(self, obj)
339 pass
340 else:
--> 341 return printer(obj)
342 # Finally look for special method names
343 method = get_real_method(obj, self.print_method)
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/IPython/core/pylabtools.py in <lambda>(fig)
246
247 if 'png' in formats:
--> 248 png_formatter.for_type(Figure, lambda fig: print_figure(fig, 'png', **kwargs))
249 if 'retina' in formats or 'png2x' in formats:
250 png_formatter.for_type(Figure, lambda fig: retina_figure(fig, **kwargs))
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/IPython/core/pylabtools.py in print_figure(fig, fmt, bbox_inches, **kwargs)
130 FigureCanvasBase(fig)
131
--> 132 fig.canvas.print_figure(bytes_io, **kw)
133 data = bytes_io.getvalue()
134 if fmt == 'svg':
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/matplotlib/backend_bases.py in print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, **kwargs)
2061 if bbox_inches:
2062 if bbox_inches == "tight":
-> 2063 renderer = _get_renderer(
2064 self.figure,
2065 functools.partial(
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/matplotlib/backend_bases.py in _get_renderer(figure, print_method)
1532 with cbook._setattr_cm(figure, draw=_draw):
1533 try:
-> 1534 print_method(io.BytesIO())
1535 except Done as exc:
1536 figure._cachedRenderer, = exc.args
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py in print_png(self, filename_or_obj, metadata, pil_kwargs, *args, **kwargs)
512 }
513
--> 514 FigureCanvasAgg.draw(self)
515 if pil_kwargs is not None:
516 from PIL import Image
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py in draw(self)
388 self.renderer = self.get_renderer(cleared=True)
389 # Acquire a lock on the shared font cache.
--> 390 with RendererAgg.lock, \
391 (self.toolbar._wait_cursor_for_draw_cm() if self.toolbar
392 else nullcontext()):
~/anaconda3/envs/ipympl/lib/python3.8/contextlib.py in __enter__(self)
111 del self.args, self.kwds, self.func
112 try:
--> 113 return next(self.gen)
114 except StopIteration:
115 raise RuntimeError("generator didn't yield") from None
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/matplotlib/backend_bases.py in _wait_cursor_for_draw_cm(self)
2774 yield
2775 finally:
-> 2776 self.set_cursor(self._lastCursor)
2777 else:
2778 yield
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/matplotlib/backends/backend_webagg_core.py in set_cursor(self, cursor)
379 def set_cursor(self, cursor):
380 if cursor != self.cursor:
--> 381 self.canvas.send_event("cursor", cursor=cursor)
382 self.cursor = cursor
383
~/anaconda3/envs/ipympl/lib/python3.8/site-packages/matplotlib/backends/backend_webagg_core.py in send_event(self, event_type, **kwargs)
344
345 def send_event(self, event_type, **kwargs):
--> 346 self.manager._send_event(event_type, **kwargs)
347
348
AttributeError: 'NoneType' object has no attribute '_send_event' but this is then fixed on |
This pull request introduces 3 alerts when merging f8e83f7 into 58bdb1e - view on LGTM.com new alerts:
|
I just found this bug this morning - great to see a fix on the way! |
I don't get what those two new alerts are, see https://lgtm.com/projects/g/matplotlib/ipympl/rev/pr-216ee8606156138123b45a51f47712789632b603
Any idea @ianhi ? |
I'm confused as well, especially because I didn't modify the toolbar at all. I think traitlets 5 was released between this and the last time the lgtm ran on this repo so maybe that's whats going on? I can't figure out how to view the build logs for pull requests on lgtm.com so its tricky to check, but in a new conda env pip install ipympl pulls in traitlets==5.0.4 for me so it's likely that lgtm picked that up. Maybe we should try requiring traitlets <5 and see if that fixes it. |
Good catch that might be it, although if it's static analysis it should not rely on dependency versions.. Let's merge your PR as it is. |
🎉 hooray! For the new release when updating the readme should there be a new column that lists matplotlib versions? |
Good idea, thanks! I'll do the release first thing tomorrow. |
Released 0.5.8, it's available from pypi and soon from conda |
fixes: #252
I also preemptively removed several other attributes that aren't used by the
js
and so do not need to be traitlets.I left
force_full
,_current_image_mode
and_dpi_ratio
as these have code of the js side that could use them, although currently all of the values for those are hardcoded in the js and the traitlets aren't used.attn: @martinRenou @tacaswell
Could a release be made after merging this?