-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Supporting different alphas for face and edge colours #1954
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
Conversation
The test results are looking good - there is a lot of change here which needs to be considered, but I'd like to target this for v1.3. Amazing work @Westacular. |
Thanks. Just noticed the Travis build had failed. I didn't have inkscape installed, so I didn't notice there was a regression with SVG in my own testing. I've since fixed the problem (hatches were not having their alpha applied in SVGs). |
Wooho! Travis caught a genuine problem! 😄 |
@Westacular: Would you mind rebasing this on current master so that this will merge cleanly and the tests will run again? |
…ll be rendered as black. Also fixes test case result that hit this bug
Specifically, alters the base, AGG, PDF, PGF, SVG, Cairo, and Mac OS X backends to better enable the use of RGBA color values for both fills and edges. An explicit alpha attribute, if set, will override the alpha channels of the color values. Updates test results, which are now what would be expected. Also fixes a couple bugs with handling of linestyles.
Done. (Also squashed some of the commits, where it made sense.) |
@@ -289,7 +289,7 @@ def _write_default_style(self): | |||
writer = self.writer | |||
default_style = generate_css({ | |||
u'stroke-linejoin': u'round', | |||
u'stroke-linecap': u'square'}) | |||
u'stroke-linecap': u'butt'}) |
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 -- indeed the "default" according to the SVG spec is butt.
Thanks for all of this work. It looks great. I think it's significant enough that it should have an entry in what's new -- and perhaps in API changes, if there's a way of summarizing changes in behavior between old and new (even though old was obviously broken)... |
Definately. |
self._rgb = fg | ||
else: | ||
self._rgb = colors.colorConverter.to_rgba(fg) | ||
if len(self._rgb) == 4 and not self._forced_alpha: | ||
self.set_alpha(self._rgb[3]) |
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 subtle, but I think it will break the non forced alpha case.
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.
Question: Should calling set_alpha
turn on the forced_alpha
value?
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.
set_alpha
does turn on _force_alpha
-- in fact, it already did, I didn't need to change anything there. (But prior these changes, practically nothing actually paid attention to it.) Calling gc.set_alpha(None)
clears _forced_alpha
.
This doesn't break the non-forced alpha case because the backends themselves, where appropriate, now pull the alpha value straight out of _rgb[3]
in the non forced alpha case.
Happy to help. I took a crack a explaining the high-level/user-facing changes, while omitting the finer details of other bugs that were fixed or how backends were changed. Let me know what you think. |
:class:`~matplotlib.patches.Patch` had ``alpha=None``, the alpha component | ||
of ``edgecolor`` would be applied to both the edge and face. | ||
|
||
* For :class:`~matplotlib.patches.Patch`, the ``capstyle`` used is now |
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 SVG only, right?
I see this as the "open heart surgery" of v1.3 (@mdboom's terminology used for a PR of mine on transforms in v1.2). I think on the whole the behaviour is more consistent, expected and desirable as a result of this PR, and it is for that reason (and the thoroughness of @Westacular's work) that I'd be comfortable merging this. 👍 - awesome work @Westacular! |
Agreed! Awesome work! I know this issue has been brought up by @efiring a number of times over the years, so I thought I'd give him the opportunity to comment before merging, just in case there's anything additional. |
I'm happy to see this. There is one change in the formally public API that could be mentioned in API_CHANGES: in GraphicsContext*.set_foreground, the isRGB kwarg is now isRGBA. I think the change is fine, and it is unlikely that user code is calling this low-level method directly, so I don't think a deprecation process is needed. |
Ok, I've added a note about the isRGBA change. Thanks for the kind words... And thanks for trusting me with the scalpel. :) |
Supporting different alphas for face and edge colours
This is a set of changes that solve the issues raised by #1899 and #1938.
Linestyles
Ignore what I said before in #1899 about linestyles.
Turns out it was working correctly for patches, but the dashes and dots were all overlapping at
linewidth=5
. The culprit is a single line inPatch.draw()
that was setting the gc to use 'projecting' capstyle. This capstyle causes the rendered length of dashes and dots to increase in proportion to the width, however, the spacing between them (which ignores the caps) remains constant. Atlinewidth=5
the spaces are completely covered by the caps, making it look likelinestyle='solid'
.Letting
capstyle='butt'
, the default, fixes this.(Also, there was a bug in the PGF backend that was causing Collections (or anything with a custom dash pattern) to always use a solid linestyle. Fixed that.)
Also, for some reason, in the SVG header
stroke-linecap:square
(the translation ofcapstyle='projecting'
) was being set as the default, even though the default for most objects isbutt
. This was causing a problem with the rendering of the PathCollection, because (at least on WebKit) the style for the collection, which did specifybutt
, was not overriding that default. The net effect was the same as the above problem for patches.Mixed Edge and Face Alpha Values
There was already stubs of logic (and a
_forced_alpha
attribute of GraphicsContext) for the notion that if an explicit alpha is set (throughgc.set_alpha()
) it should override any face and edge alphas, but otherwise, leave them be; however, it was largely ignored by most backends, each of which tended to do its own slightly different thing with regard which it recognized and how it handled them.I've updated (and tested to varying degrees) the AGG, PDF, SVG, PGF, Mac OS X, and Cairo backends, along with various fixes to the backend bases and to the Patch class. As far as I can tell, that covers everything that's already paying attention to the
gc.get_alpha()
value.I also fixed the bug (also discussed at #1938) where setting an alpha value on the patch would override
edgecolor='none'
. The new behaviour is that the value given toalpha
is ignored by the edge colour if and only ifedgecolor='none'
exactly;edgecolor=(x,x,x,0)
still gets overridden byalpha
. This is the existing behaviour forfacecolor
, which I've not changed.I've included the test (and changes) added by @pelson in #1899, along with correct results, and corrected the results of the
clip_to_bbox
test (which were previously affected by the alpha=x/edgecolor='none' bug). I've also added another test to check that the alpha attribute is overriding the alpha components of the face and edge colors.