-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Backends cleanup #8772
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
Backends cleanup #8772
Conversation
def __init__(self, figure): | ||
if DEBUG: | ||
print('FigureCanvasQtAgg: ', figure) | ||
FigureCanvasQT.__init__(self, figure) |
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.
I think this needs to be here or the MI does not work correctly (as pyqt5 made them cooperative, but they are not int pyqt4)
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.
This is further handled by the qtcairo commit, but in fact with the new MRO (specifically, due to FigureCanvasQT going after FigureCanvasAgg), this is not needed anymore, because the MRO FigureCanvasQT(4)Agg is
matplotlib.backends.backend_qt4agg.FigureCanvasQTAgg
matplotlib.backends.backend_qt5agg.FigureCanvasQTAggBase
matplotlib.backends.backend_agg.FigureCanvasAgg
matplotlib.backends.backend_qt4.FigureCanvasQT
matplotlib.backends.backend_qt5.FigureCanvasQT
PyQt4.QtGui.QWidget
PyQt4.QtCore.QObject
sip.wrapper
PyQt4.QtGui.QPaintDevice
sip.simplewrapper
matplotlib.backend_bases.FigureCanvasBase
builtins.object
and FigureCanvasAgg.__init__
is the same as FigureCanvasBase.__init__
, which does not forward its arguments to the super class, so QWidget never sees the figure kwarg.
Or you can just test by yourself that it works :)
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.
Ah, I was lost in the classes here. It looks like the calls out to the PyQt base classes happen in the FigureCanvasQt.__init__
not here.
🐑
|
||
class FigureCanvasQTAgg(FigureCanvasQTAggBase, | ||
FigureCanvasQT, FigureCanvasAgg): | ||
class FigureCanvasQTAgg(FigureCanvasQTAggBase, FigureCanvasQT): |
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.
I think having the base class come in as the _
version of this is clearer (I had to think a bit for why this should work).
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.
Actually this MRO chain will get even further simplified in #8771 (to class FigureCanvasQTAgg(FigureCanvasAgg, FigureCanvasQT)
, which seems as simple as one can do :-)), sorry for modifying the same thing twice.
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.
I am very much 👍 on simplifying the MRO.
# into argb format and is in a 4 byte unsigned int. Little endian | ||
# system is LSB first and expects the bytes in reverse order | ||
# (bgra). | ||
if QtCore.QSysInfo.ByteOrder == QtCore.QSysInfo.LittleEndian: |
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.
Why drop the little endian support?
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.
I'm just reusing the blitting codepath for both cases, so either region.to_string_argb
(which is a different method from renderer.tostring_argb
...) was already doing the right thing wrt. endianness, or there has been a bug for a while on one of the two endiannesses that no one ever noticed.
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.
fair. There are not many little-endian systems left in practice (and they tend to be big main frame type systems these days).
rect = qImage.rect() | ||
p = QtGui.QPainter(self) | ||
# reset the image area of the canvas to be the back-ground color | ||
p.eraseRect(rect) |
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.
This is important if users have alpha in the final rgba. If this is not here text appears to 'get thicker' over time as the alpha stacks up.
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.
Good catch, restored the erase in the case where bbox_queue is empty.
@@ -244,14 +190,11 @@ def __init__(self, figure): | |||
if DEBUG: | |||
print('FigureCanvasQtAgg: ', figure) | |||
super(FigureCanvasQTAgg, self).__init__(figure=figure) | |||
self._drawRect = None | |||
self.blitbox = [] |
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.
This going private needs to be documented and gracefully deprecated. Users who use blitting
are extra clever and are likely abusing this.
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.
done (modulo comment below)
# Adjust the buf reference count to work around a memory | ||
# leak bug in QImage under PySide on Python 3. | ||
if QT_API == 'PySide' and six.PY3: | ||
ctypes.c_long.from_address(id(buf)).value = 1 |
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.
I am curious what the history on why we had this done two different ways was.
@@ -56,12 +59,6 @@ | |||
from matplotlib.transforms import Bbox, Affine2D | |||
from matplotlib.font_manager import ttfFontProperty | |||
|
|||
# Image::color_conv(format) for draw_image() |
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.
@@ -509,7 +476,7 @@ def print_svg(self, fobj, *args, **kwargs): | |||
def print_svgz(self, fobj, *args, **kwargs): | |||
return self._save(fobj, 'svgz', *args, **kwargs) | |||
|
|||
def _save (self, fo, format, **kwargs): | |||
def _save(self, fo, fmt, **kwargs): |
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.
I will grumble a bit about this, but it is OK. It is a private API and the change is to avoid shadowing a builtin.
I think the biggest concern I have with this is the dropping of |
You mean blitbox? I made it a deprecated property, do you want an API change there? (tbh I am not sure how that would help anyone, there is simply no replacement for it (other than calling |
0194395
to
1f50a0f
Compare
New version pushed. |
1f50a0f
to
0fd5b04
Compare
@@ -75,9 +63,14 @@ def drawRectangle(self, rect): | |||
self._drawRect = None | |||
self.update() | |||
|
|||
@property | |||
@cbook.deprecated("2.0") |
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.
Should this be 2.1?
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, fixed
0fd5b04
to
6ce2f06
Compare
On 2017/06/20 12:51 AM, Thomas A Caswell wrote:
***@***.**** commented on this pull request.
------------------------------------------------------------------------
In lib/matplotlib/backends/backend_qt5agg.py
<#8772 (comment)>:
> @@ -86,88 +84,37 @@ def paintEvent(self, e):
if not hasattr(self, 'renderer'):
return
- if DEBUG:
- print('FigureCanvasQtAgg.paintEvent: ', self,
- self.get_width_height())
-
- if len(self.blitbox) == 0:
- # matplotlib is in rgba byte order. QImage wants to put the bytes
- # into argb format and is in a 4 byte unsigned int. Little endian
- # system is LSB first and expects the bytes in reverse order
- # (bgra).
- if QtCore.QSysInfo.ByteOrder == QtCore.QSysInfo.LittleEndian:
fair. There are not many little-endian systems left in practice (and
they tend to be big main frame type systems these days).
For the record, I think you meant "big-endian".
|
6ce2f06
to
22457f3
Compare
power-cycled to retrigger CI. |
|
||
if self._bbox_queue: | ||
bbox_queue = self._bbox_queue | ||
self._bbox_queue = [] |
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.
Do not need this line, unconditionally reset below.
@@ -196,7 +141,7 @@ def __draw_idle_agg(self, *args): | |||
self._agg_draw_pending = False | |||
return | |||
try: | |||
FigureCanvasAgg.draw(self) | |||
super(FigureCanvasQTAggBase, self).draw() |
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.
This can be simplified to self.draw()
self.ctx.set_line_width (self.renderer.points_to_pixels(w)) | ||
|
||
|
||
def new_figure_manager(num, *args, **kwargs): # called by backends/__init__.py |
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.
I think this change leaked when you split the changes up?
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.
Left 3 small comments, ok with this going in with out them being addressed.
Comments handled. |
Follow a similar architecture to the Gtk3Agg backend: a default draw can be implemented as a blitting of the entire canvas. Also unify the Qt4Agg and Qt5Agg canvas classes a bit more.
The removed comment in backend_agg regarding rgb came in in 281b7b7, but is now irrelevant.
Last commit removes some old comments, rewords some docstrings, reformats a few lines. |
This is the first part of #8771, split out for simpler review.