Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Different alphas for lines and fills. #1899

Closed
wants to merge 1 commit into from

4 participants

@pelson
Collaborator

I saw an interesting question on Stackoverflow the other day for which I found it was possible to supply an RGBA for both face and edge colors separately. I'm guessing this isn't tested, so thought I would add a comprehensive test, unfortunately the test results are wrong (so don't merge this).

Am I doing something silly in the test?

@pelson
Collaborator

@mdboom - the two polygons, from what I can tell, should be identical. Clearly they are nowhere near. Is this something you'd expect? If not, I've already got a test that I can work towards fixing :smile:

@mdboom
Owner

Yes -- I agree they should look the same. I wonder if this is related to #1860 in any way... we should probably at least try this on either side of it to check.

@mdboom
Owner

Well -- probably not, actually, since I don't think #1860 would affect the Agg backend.

@Westacular

I spent some time looking into this. The differences between how a patch and a collection in handle alpha values runs quite deep.

Basically, for the backends I've looked at (AGG, macosx, and the base classes), renderer.draw_path (which is what Patch classes call) is NOT capable of having a different alphas for the edge and the face. This seems to be by design. When calling draw_path, the alpha channel value in rgbFace (if present) is overridden by the alpha value of the GraphicsContext (which is in turn either set explicitly, or inferred from the alpha value of the edgecolor, if it's in RGBA format).

renderer.draw_path_collection (used to render Collection classes), on the other hand, has no explicit parameter(s) for alpha value -- it only has edgecolors and facecolors -- and the backends generally implement draw_path_collection independently of draw_path, using code paths that handle RGBA values for edgecolors and facecolors correctly.

To fix Patches to support distinct alpha values, you'd need to make some non-trivial changes to how colours are handled in multiple backends (both in Renderers and GraphicsContexts), the Patch class itself, and possibly also the backend base classes.

The absence of the proper linestyle for the Patch, on the other hand, is an easy-to-fix bug; GraphicsContext.set_linestyle seems to be ignored by backends in favour of GraphicsContext.set_dashes. The Patch class should do the conversion from linestyle to dashes itself (as Collection.set_linestyle does).

@pelson
Collaborator

Thanks @Westacular - nice write-up of what has clearly been some thorough investigation. Did you manage to see why the two red facecolors had different alphas? Does setting an alpha on an edgecolor modify the alpha of the face?

@mdboom
Owner

Yes, thanks for that, @Westacular: This is a long-standing shortcoming, and one I'd like to fix. The difficulty has always been how to do it in a backward-compatible way -- or at least a way that handles the majority of existing uses in the wild.

@Westacular

@pelson Yes, the alpha component of edgecolor overrides any alpha component in facecolor, except in the special case when facecolor=(x,x,x,0), for which the face is invisible.

I did some testing as to the output produced by different combinations of the alpha, facecolor, and edgecolor arguments. The results:

Case 1:

alpha unset
facecolor not 'none' (and alpha not 0)
edgecolor not 'none' (and alpha not 0)

face and edge both rendered using the alpha value from edgecolor. If edgecolor is set using something other than an RGBA value, alpha=1 for both.

Case 2:

alpha set
facecolor not 'none' (and alpha not 0)
edgecolor not 'none' (and alpha not 0)

face and edge both rendered using the explicitly set alpha value

Case 3:

alpha unset
facecolor not 'none' (and alpha not 0)
edgecolor='none' OR its alpha=0

edge is invisible, face rendered using its own alpha value

Case 4:

alpha unset
facecolor not 'none' (and alpha not 0)
edgecolor unset

edge is default color (black for me), both edge and face rendered with alpha=1.

Case 5:

alpha set
facecolor not 'none' (and alpha not 0)
edgecolor set with its alpha=0

face and edge both rendered using the explicitly set alpha value.

Case 6:

alpha set
facecolor not 'none' (and alpha not 0)
edgecolor='none'

face and edge both rendered using the explicitly set alpha value. edge is rendered using default color (black). This seems like it should be considered a bug.

Case 7:

alpha unset
facecolor='none' OR its alpha=0
edgecolor not 'none' (and alpha not 0)

face is invisible, edge rendered using its own alpha value

Case 8:

alpha unset
facecolor unset
edgecolor not 'none' (and alpha not 0)

face is default color (blue for me), both face and edge both rendered using alpha value of edgecolor

Case 9:

alpha set
facecolor='none'
edgecolor not 'none' (and alpha not 0)

face is invisible, edge rendered using the explicitly set alpha value

Case 10:

alpha set
facecolor set with its alpha=0
edgecolor not 'none' (and alpha not 0)

face and edge rendered using the explicitly set alpha value

Case 11:

alpha unset
facecolor='none'
edgecolor='none'

nothing is rendered (face and edge both invisible)

Case 12:

alpha unset
facecolor set with alpha=0
edgecolor set with alpha=0

nothing is rendered (face and edge both invisible)

Case 13:

alpha set
facecolor='none'
edgecolor='none'

face is invisible, edge is rendered using default color with the explicitly set alpha value. Seems like the same bug as case 6.

Case 14:

alpha set
facecolor set with alpha=0
edgecolor set with alpha=0

face and edge both rendered using their respective colors, with the explicitly set alpha value


In general, I think the most backward-compatible way to fix this would be to maintain the logic that the alpha argument overrides the alpha components of both facecolor and edgecolor, but change it so that if alpha=None, the facecolor and edgecolor alpha components are independently preserved. This would mean altering the output for cases 1, 4, and 8 in the above list.

However, implementing this would require making potentially delicate changes to how the backends handle the combination of gc.set_alpha, gc.set_foreground (=edgecolor), and the rgbFace argument to the renderer (=facecolor); currently, at least for the draw_path methods, alpha components for both foreground and rgbFace are always ignored, regardless of whether the gc's alpha attribute has been set.

(Also, the bug in cases 6 and 13 should be fixed, so that edgecolor='none' is not overridden by setting alpha. That part should be a relatively straightforward fix to just the Patch class).

I'll go ahead and fix the little bugs affecting only the Patch class, and if you think it's worth a shot, I can take a crack at making the additional changes to the backends.

@pelson
Collaborator

I'll go ahead and fix the little bugs affecting only the Patch class, and if you think it's worth a shot, I can take a crack at making the additional changes to the backends.

@Westacular - you have my support to change this for the better. Given your detailed review, it sounds like your changes will be well considered, minimise the disruption and result in more sensible behaviour. In short, go for it!

@efiring
Owner

Closed based on having merged #1954.

@efiring efiring closed this
@pelson pelson referenced this pull request
Merged

Rastized background color #2479

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 12, 2013
  1. @pelson

    Failing tests.

    pelson authored
This page is out of date. Refresh to see the latest.
View
BIN  lib/matplotlib/tests/baseline_images/test_patches/patch_alpha_coloring.pdf
Binary file not shown
View
BIN  lib/matplotlib/tests/baseline_images/test_patches/patch_alpha_coloring.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
311 lib/matplotlib/tests/baseline_images/test_patches/patch_alpha_coloring.svg
@@ -0,0 +1,311 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
+ "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!-- Created with matplotlib (http://matplotlib.org/) -->
+<svg height="432pt" version="1.1" viewBox="0 0 576 432" width="576pt" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <defs>
+ <style type="text/css">
+*{stroke-linecap:square;stroke-linejoin:round;}
+ </style>
+ </defs>
+ <g id="figure_1">
+ <g id="patch_1">
+ <path d="
+M0 432
+L576 432
+L576 0
+L0 0
+z
+" style="fill:#ffffff;"/>
+ </g>
+ <g id="axes_1">
+ <g id="patch_2">
+ <path d="
+M72 388.8
+L518.4 388.8
+L518.4 43.2
+L72 43.2
+z
+" style="fill:#ffffff;"/>
+ </g>
+ <g id="PathCollection_1">
+ <defs>
+ <path d="
+M369.6 -158.4
+C409.062 -158.4 446.913 -170.538 474.817 -192.141
+C502.721 -213.744 518.4 -243.049 518.4 -273.6
+C518.4 -304.151 502.721 -333.456 474.817 -355.059
+C446.913 -376.662 409.062 -388.8 369.6 -388.8
+C330.138 -388.8 292.287 -376.662 264.383 -355.059
+C236.479 -333.456 220.8 -304.151 220.8 -273.6
+C220.8 -243.049 236.479 -213.744 264.383 -192.141
+C292.287 -170.538 330.138 -158.4 369.6 -158.4
+z
+
+M369.6 -388.8
+L406.8 -323.483
+L498.465 -331.2
+L444 -273.6
+L498.465 -216
+L406.8 -223.717
+L369.6 -158.4
+L332.4 -223.717
+L240.735 -216
+L295.2 -273.6
+L240.735 -331.2
+L332.4 -323.483
+z
+" id="C0_0_2d53bfaf78"/>
+ </defs>
+ <g clip-path="url(#p7ff5b81e1d)">
+ <use style="fill:#ff0000;opacity:0.375;stroke:#0000ff;stroke-dasharray:3.000000,5.000000,1.000000,5.000000;stroke-dashoffset:0.0;stroke-linecap:butt;stroke-width:5.0;" x="0.0" xlink:href="#C0_0_2d53bfaf78" y="432.0"/>
+ </g>
+ </g>
+ <g id="patch_3">
+ <path clip-path="url(#p7ff5b81e1d)" d="
+M220.8 388.8
+C260.262 388.8 298.113 376.662 326.017 355.059
+C353.921 333.456 369.6 304.151 369.6 273.6
+C369.6 243.049 353.921 213.744 326.017 192.141
+C298.113 170.538 260.262 158.4 220.8 158.4
+C181.338 158.4 143.487 170.538 115.583 192.141
+C87.6785 213.744 72 243.049 72 273.6
+C72 304.151 87.6785 333.456 115.583 355.059
+C143.487 376.662 181.338 388.8 220.8 388.8
+z
+
+M220.8 158.4
+L258 223.717
+L349.665 216
+L295.2 273.6
+L349.665 331.2
+L258 323.483
+L220.8 388.8
+L183.6 323.483
+L91.9354 331.2
+L146.4 273.6
+L91.9354 216
+L183.6 223.717
+z
+" style="fill:#ff0000;opacity:0.75;stroke:#0000ff;stroke-dasharray:3.000000,5.000000,1.000000,5.000000;stroke-dashoffset:0.0;stroke-width:5;"/>
+ </g>
+ <g id="matplotlib.axis_1">
+ <g id="xtick_1">
+ <g id="line2d_1">
+ <defs>
+ <path d="
+M0 0
+L0 -4" id="mcb557df647" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/>
+ </defs>
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_2">
+ <defs>
+ <path d="
+M0 0
+L0 4" id="mdad270ee8e" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/>
+ </defs>
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_2">
+ <g id="line2d_3">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="146.4" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_4">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="146.4" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_3">
+ <g id="line2d_5">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="220.8" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_6">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="220.8" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_4">
+ <g id="line2d_7">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="295.2" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_8">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="295.2" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_5">
+ <g id="line2d_9">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="369.6" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_10">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="369.6" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_6">
+ <g id="line2d_11">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="444.0" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_12">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="444.0" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ </g>
+ <g id="xtick_7">
+ <g id="line2d_13">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#mcb557df647" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_14">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#mdad270ee8e" y="43.2"/>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g id="matplotlib.axis_2">
+ <g id="ytick_1">
+ <g id="line2d_15">
+ <defs>
+ <path d="
+M0 0
+L4 0" id="mc8fcea1516" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/>
+ </defs>
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="388.8"/>
+ </g>
+ </g>
+ <g id="line2d_16">
+ <defs>
+ <path d="
+M0 0
+L-4 0" id="m0d5b0a6425" style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;"/>
+ </defs>
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="388.8"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_2">
+ <g id="line2d_17">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="331.2"/>
+ </g>
+ </g>
+ <g id="line2d_18">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="331.2"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_3">
+ <g id="line2d_19">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="273.6"/>
+ </g>
+ </g>
+ <g id="line2d_20">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="273.6"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_4">
+ <g id="line2d_21">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="216.0"/>
+ </g>
+ </g>
+ <g id="line2d_22">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="216.0"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_5">
+ <g id="line2d_23">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="158.4"/>
+ </g>
+ </g>
+ <g id="line2d_24">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="158.4"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_6">
+ <g id="line2d_25">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="100.8"/>
+ </g>
+ </g>
+ <g id="line2d_26">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="100.8"/>
+ </g>
+ </g>
+ </g>
+ <g id="ytick_7">
+ <g id="line2d_27">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="72.0" xlink:href="#mc8fcea1516" y="43.2"/>
+ </g>
+ </g>
+ <g id="line2d_28">
+ <g>
+ <use style="stroke:#000000;stroke-linecap:butt;stroke-width:0.5;" x="518.4" xlink:href="#m0d5b0a6425" y="43.2"/>
+ </g>
+ </g>
+ </g>
+ </g>
+ <g id="patch_4">
+ <path d="
+M72 43.2
+L518.4 43.2" style="fill:none;stroke:#000000;"/>
+ </g>
+ <g id="patch_5">
+ <path d="
+M518.4 388.8
+L518.4 43.2" style="fill:none;stroke:#000000;"/>
+ </g>
+ <g id="patch_6">
+ <path d="
+M72 388.8
+L518.4 388.8" style="fill:none;stroke:#000000;"/>
+ </g>
+ <g id="patch_7">
+ <path d="
+M72 388.8
+L72 43.2" style="fill:none;stroke:#000000;"/>
+ </g>
+ </g>
+ </g>
+ <defs>
+ <clipPath id="p7ff5b81e1d">
+ <rect height="345.6" width="446.4" x="72.0" y="43.2"/>
+ </clipPath>
+ </defs>
+</svg>
View
43 lib/matplotlib/tests/test_collections.py
@@ -2,7 +2,7 @@
Tests specific to the collections module.
"""
-import nose.tools
+from nose.tools import assert_equal
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.collections import EventCollection
@@ -81,7 +81,7 @@ def test__EventCollection__get_orientation():
orientation
'''
_, coll, props = generate_EventCollection_plot()
- nose.tools.assert_equal(props['orientation'], coll.get_orientation())
+ assert_equal(props['orientation'], coll.get_orientation())
@cleanup
@@ -91,7 +91,7 @@ def test__EventCollection__is_horizontal():
orientation
'''
_, coll, _ = generate_EventCollection_plot()
- nose.tools.assert_equal(True, coll.is_horizontal())
+ assert_equal(True, coll.is_horizontal())
@cleanup
@@ -100,7 +100,7 @@ def test__EventCollection__get_linelength():
check to make sure the default linelength matches the input linelength
'''
_, coll, props = generate_EventCollection_plot()
- nose.tools.assert_equal(props['linelength'], coll.get_linelength())
+ assert_equal(props['linelength'], coll.get_linelength())
@cleanup
@@ -109,7 +109,7 @@ def test__EventCollection__get_lineoffset():
check to make sure the default lineoffset matches the input lineoffset
'''
_, coll, props = generate_EventCollection_plot()
- nose.tools.assert_equal(props['lineoffset'], coll.get_lineoffset())
+ assert_equal(props['lineoffset'], coll.get_lineoffset())
@cleanup
@@ -118,7 +118,7 @@ def test__EventCollection__get_linestyle():
check to make sure the default linestyle matches the input linestyle
'''
_, coll, _ = generate_EventCollection_plot()
- nose.tools.assert_equal(coll.get_linestyle(), [(None, None)])
+ assert_equal(coll.get_linestyle(), [(None, None)])
@cleanup
@@ -213,8 +213,8 @@ def test__EventCollection__switch_orientation():
splt, coll, props = generate_EventCollection_plot()
new_orientation = 'vertical'
coll.switch_orientation()
- nose.tools.assert_equal(new_orientation, coll.get_orientation())
- nose.tools.assert_equal(False, coll.is_horizontal())
+ assert_equal(new_orientation, coll.get_orientation())
+ assert_equal(False, coll.is_horizontal())
new_positions = coll.get_positions()
check_segments(coll,
new_positions,
@@ -236,8 +236,8 @@ def test__EventCollection__switch_orientation_2x():
coll.switch_orientation()
coll.switch_orientation()
new_positions = coll.get_positions()
- nose.tools.assert_equal(props['orientation'], coll.get_orientation())
- nose.tools.assert_equal(True, coll.is_horizontal())
+ assert_equal(props['orientation'], coll.get_orientation())
+ assert_equal(True, coll.is_horizontal())
np.testing.assert_array_equal(props['positions'], new_positions)
check_segments(coll,
new_positions,
@@ -255,8 +255,8 @@ def test__EventCollection__set_orientation():
splt, coll, props = generate_EventCollection_plot()
new_orientation = 'vertical'
coll.set_orientation(new_orientation)
- nose.tools.assert_equal(new_orientation, coll.get_orientation())
- nose.tools.assert_equal(False, coll.is_horizontal())
+ assert_equal(new_orientation, coll.get_orientation())
+ assert_equal(False, coll.is_horizontal())
check_segments(coll,
props['positions'],
props['linelength'],
@@ -275,7 +275,7 @@ def test__EventCollection__set_linelength():
splt, coll, props = generate_EventCollection_plot()
new_linelength = 15
coll.set_linelength(new_linelength)
- nose.tools.assert_equal(new_linelength, coll.get_linelength())
+ assert_equal(new_linelength, coll.get_linelength())
check_segments(coll,
props['positions'],
new_linelength,
@@ -293,7 +293,7 @@ def test__EventCollection__set_lineoffset():
splt, coll, props = generate_EventCollection_plot()
new_lineoffset = -5.
coll.set_lineoffset(new_lineoffset)
- nose.tools.assert_equal(new_lineoffset, coll.get_lineoffset())
+ assert_equal(new_lineoffset, coll.get_lineoffset())
check_segments(coll,
props['positions'],
props['linelength'],
@@ -311,7 +311,7 @@ def test__EventCollection__set_linestyle():
splt, coll, _ = generate_EventCollection_plot()
new_linestyle = 'dashed'
coll.set_linestyle(new_linestyle)
- nose.tools.assert_equal(coll.get_linestyle(), [(0, (6.0, 6.0))])
+ assert_equal(coll.get_linestyle(), [(0, (6.0, 6.0))])
splt.set_title('EventCollection: set_linestyle')
@@ -323,7 +323,7 @@ def test__EventCollection__set_linewidth():
splt, coll, _ = generate_EventCollection_plot()
new_linewidth = 5
coll.set_linewidth(new_linewidth)
- nose.tools.assert_equal(coll.get_linewidth(), new_linewidth)
+ assert_equal(coll.get_linewidth(), new_linewidth)
splt.set_title('EventCollection: set_linewidth')
@@ -362,10 +362,10 @@ def check_segments(coll, positions, linelength, lineoffset, orientation):
# test to make sure each segment is correct
for i, segment in enumerate(segments):
- nose.tools.assert_equal(segment[0, pos1], lineoffset + linelength / 2.)
- nose.tools.assert_equal(segment[1, pos1], lineoffset - linelength / 2.)
- nose.tools.assert_equal(segment[0, pos2], positions[i])
- nose.tools.assert_equal(segment[1, pos2], positions[i])
+ assert_equal(segment[0, pos1], lineoffset + linelength / 2.)
+ assert_equal(segment[1, pos1], lineoffset - linelength / 2.)
+ assert_equal(segment[0, pos2], positions[i])
+ assert_equal(segment[1, pos2], positions[i])
def check_allprop(values, target):
@@ -375,7 +375,7 @@ def check_allprop(values, target):
note: this is not a test, it is used by tests
'''
for value in values:
- nose.tools.assert_equal(value, target)
+ assert_equal(value, target)
def check_allprop_array(values, target):
@@ -387,6 +387,7 @@ def check_allprop_array(values, target):
for value in values:
np.testing.assert_array_equal(value, target)
+
if __name__ == '_main_':
import nose
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)
View
36 lib/matplotlib/tests/test_patches.py
@@ -9,7 +9,8 @@
from matplotlib.patches import Rectangle
from matplotlib.testing.decorators import image_comparison
import matplotlib.pyplot as plt
-from matplotlib import patches as mpatches
+import matplotlib.patches as mpatches
+import matplotlib.collections as mcollections
from matplotlib import path as mpath
from matplotlib import transforms as mtrans
@@ -104,3 +105,36 @@ def test_clip_to_bbox():
result_path, alpha=0.5, facecolor='green', lw=4, edgecolor='black')
ax.add_patch(result_patch)
+
+
+@image_comparison(baseline_images=['patch_alpha_coloring'], remove_text=True)
+def test_patch_alpha_coloring():
+ star = mpath.Path.unit_regular_star(6)
+ circle = mpath.Path.unit_circle()
+ # concatenate the star with an internal cutout of the circle
+ verts = np.concatenate([circle.vertices, star.vertices[::-1]])
+ codes = np.concatenate([circle.codes, star.codes])
+ cut_star1 = mpath.Path(verts, codes)
+ cut_star2 = mpath.Path(verts + 1, codes)
+
+ ax = plt.axes()
+ patch = mpatches.PathPatch(cut_star1,
+ linewidth=5, linestyle='dashdot',
+ facecolor=(1, 0, 0, 0.5),
+ edgecolor=(0, 0, 1, 0.75))
+ ax.add_patch(patch)
+
+ col = mcollections.PathCollection([cut_star2],
+ linewidth=5, linestyles='dashdot',
+ facecolor=(1, 0, 0, 0.5),
+ edgecolor=(0, 0, 1, 0.75))
+ ax.add_collection(col)
+
+ ax.set_xlim([-1, 2])
+ ax.set_ylim([-1, 2])
+
+
+
+if __name__=='__main__':
+ import nose
+ nose.runmodule(argv=['-s','--with-doctest'], exit=False)
Something went wrong with that request. Please try again.