|
From: Andrew D. <da...@at...> - 2013-03-12 16:13:51
|
Hi
I'd like to be able to clip a line so that the portion of it lying outside
of a given polygon remains visible and the part that lies inside of the
polygon is not visible. What I want is basically the opposite of:
line.set_clip_path(polygon)
which leaves only the part of the line inside the polygon visible. Is this
possible?
I know I can just fill the polygon with the background color or something
but this gets messy when there are other lines on the plot that don't need
to be clipped.
Thanks,
Andrew
|
|
From: Phil E. <pel...@gm...> - 2013-03-12 16:43:27
Attachments:
clipped.png
|
You could just use paths which have holes in them, making the exterior so
broad that you wouldn't notice the edge of the clipping. I've put together
an example of doing just that:
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import matplotlib.collections as mcol
import numpy as np
import copy
exterior = mpath.Path.unit_rectangle()
exterior = mpath.Path(copy.deepcopy(exterior.vertices),
copy.deepcopy(exterior.codes[:]))
exterior.vertices *= 4
exterior.vertices -= 2
interior = mpath.Path.unit_circle()
interior.vertices = interior.vertices[::-1]
clip_path = mpath.Path(vertices=np.concatenate([exterior.vertices,
interior.vertices]),
codes=np.concatenate([exterior.codes,
interior.codes]))
star = mpath.Path.unit_regular_star(6)
star.vertices *= 2.6
ax = plt.subplot(321)
col = mcol.PathCollection([clip_path], facecolor='yellow')
ax.add_collection(col)
ax.set_title('Clip path')
ax.set_xlim([-3, 3])
ax.set_ylim([-3, 3])
ax = plt.subplot(322)
col = mcol.PathCollection([star], facecolor='red')
ax.add_collection(col)
ax.set_title('Target polygon')
ax.set_xlim([-3, 3])
ax.set_ylim([-3, 3])
ax = plt.subplot2grid((3, 2), (1, 0), colspan=2, rowspan=2)
col = mcol.PathCollection([star])
col.set_clip_path(clip_path, ax.transData)
ax.add_collection(col)
ax.set_title('Target polygon clipped by clip_path')
ax.set_xlim([-3, 3])
ax.set_ylim([-3, 3])
plt.tight_layout()
plt.show()
[image: Inline images 1]
There are other options if this doesn't cut the mustard.
HTH,
On 12 March 2013 15:37, Andrew Dawson <da...@at...> wrote:
> Hi
>
> I'd like to be able to clip a line so that the portion of it lying outside
> of a given polygon remains visible and the part that lies inside of the
> polygon is not visible. What I want is basically the opposite of:
>
> line.set_clip_path(polygon)
>
> which leaves only the part of the line inside the polygon visible. Is this
> possible?
>
> I know I can just fill the polygon with the background color or something
> but this gets messy when there are other lines on the plot that don't need
> to be clipped.
>
> Thanks,
> Andrew
>
>
> ------------------------------------------------------------------------------
> Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
> Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
> endpoint security space. For insight on selecting the right partner to
> tackle endpoint security challenges, access the full report.
> http://p.sf.net/sfu/symantec-dev2dev
> _______________________________________________
> Matplotlib-users mailing list
> Mat...@li...
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
>
|
|
From: Andrew D. <da...@at...> - 2013-03-12 18:00:37
|
I tried this and although it sort-of works, it doesn't really do what I
need. I tried using this:
import matplotlib.pyplot as plt
import matplotlib.path as mpath
import numpy as np
import copy
# create figure and axes
fig = plt.figure(figsize=(6, 6))
ax = fig.add_axes([.1, .1, .8, .8])
ax.set_xlim([-3, 3])
ax.set_ylim([-3, 3])
# a circle at the origin with radius 1
circle = plt.Circle((0, 0), 1, transform=ax.transData,
edgecolor='k', facecolor='none')
# from Phil's example
exterior = mpath.Path.unit_rectangle()
interior = circle.get_path()
exterior = mpath.Path(copy.deepcopy(exterior.vertices),
copy.deepcopy(exterior.codes[:]))
interior.vertices = interior.vertices[::-1]
exterior.vertices *= 6
exterior.vertices -= 3
clip_path = mpath.Path(vertices=np.concatenate([exterior.vertices,
interior.vertices]),
codes=np.concatenate([exterior.codes,
interior.codes]))
# lines from the origin dividing the axes into 8 sectors
end_coords = [(3, 0), (3, 3), (0, 3), (-3, 3),
(-3, 0), (-3, -3), (0, -3), (3, -3)]
for x, y in end_coords:
line, = ax.plot((x, 0), (y, 0), color='k')
line.set_clip_path(clip_path, ax.transData)
ax.add_artist(circle)
plt.show()
and the result is the attached image with_clipping.png. You should see that
the circle is no longer circular, and also there are weird line width
issues. What I want it basically exactly like the attached
without_clipping.png but with paths inside the circle removed.
Thanks
On 12 March 2013 16:43, Phil Elson <pel...@gm...> wrote:
> You could just use paths which have holes in them, making the exterior so
> broad that you wouldn't notice the edge of the clipping. I've put together
> an example of doing just that:
>
> import matplotlib.pyplot as plt
> import matplotlib.path as mpath
> import matplotlib.collections as mcol
> import numpy as np
> import copy
>
>
> exterior = mpath.Path.unit_rectangle()
> exterior = mpath.Path(copy.deepcopy(exterior.vertices),
> copy.deepcopy(exterior.codes[:]))
> exterior.vertices *= 4
> exterior.vertices -= 2
> interior = mpath.Path.unit_circle()
> interior.vertices = interior.vertices[::-1]
> clip_path = mpath.Path(vertices=np.concatenate([exterior.vertices,
> interior.vertices]),
> codes=np.concatenate([exterior.codes,
> interior.codes]))
>
> star = mpath.Path.unit_regular_star(6)
> star.vertices *= 2.6
>
>
> ax = plt.subplot(321)
> col = mcol.PathCollection([clip_path], facecolor='yellow')
> ax.add_collection(col)
> ax.set_title('Clip path')
> ax.set_xlim([-3, 3])
> ax.set_ylim([-3, 3])
>
>
> ax = plt.subplot(322)
> col = mcol.PathCollection([star], facecolor='red')
> ax.add_collection(col)
> ax.set_title('Target polygon')
> ax.set_xlim([-3, 3])
> ax.set_ylim([-3, 3])
>
>
> ax = plt.subplot2grid((3, 2), (1, 0), colspan=2, rowspan=2)
> col = mcol.PathCollection([star])
> col.set_clip_path(clip_path, ax.transData)
> ax.add_collection(col)
>
> ax.set_title('Target polygon clipped by clip_path')
> ax.set_xlim([-3, 3])
> ax.set_ylim([-3, 3])
>
> plt.tight_layout()
>
> plt.show()
>
> [image: Inline images 1]
>
>
>
> There are other options if this doesn't cut the mustard.
>
> HTH,
>
>
>
>
>
>
>
> On 12 March 2013 15:37, Andrew Dawson <da...@at...> wrote:
>
>> Hi
>>
>> I'd like to be able to clip a line so that the portion of it lying
>> outside of a given polygon remains visible and the part that lies inside of
>> the polygon is not visible. What I want is basically the opposite of:
>>
>> line.set_clip_path(polygon)
>>
>> which leaves only the part of the line inside the polygon visible. Is
>> this possible?
>>
>> I know I can just fill the polygon with the background color or something
>> but this gets messy when there are other lines on the plot that don't need
>> to be clipped.
>>
>> Thanks,
>> Andrew
>>
>>
>> ------------------------------------------------------------------------------
>> Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
>> Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
>> endpoint security space. For insight on selecting the right partner to
>> tackle endpoint security challenges, access the full report.
>> http://p.sf.net/sfu/symantec-dev2dev
>> _______________________________________________
>> Matplotlib-users mailing list
>> Mat...@li...
>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>
>>
>
--
Dr Andrew Dawson
Atmospheric, Oceanic & Planetary Physics
Clarendon Laboratory
Parks Road
Oxford OX1 3PU, UK
Tel: +44 (0)1865 282438
Email: da...@at...
Web Site: http://www2.physics.ox.ac.uk/contacts/people/dawson
|
|
From: Phil E. <pel...@gm...> - 2013-03-19 17:17:54
Attachments:
clipped.png
|
That's really weird. @mdboom, do you have any idea what the difference is
when drawing a Path which has a clip path? (I've looked at anti-aliasing &
snapping without success)
On 12 March 2013 17:17, Andrew Dawson <da...@at...> wrote:
> I tried this and although it sort-of works, it doesn't really do what I
> need. I tried using this:
>
> import matplotlib.pyplot as plt
> import matplotlib.path as mpath
> import numpy as np
> import copy
>
> # create figure and axes
> fig = plt.figure(figsize=(6, 6))
> ax = fig.add_axes([.1, .1, .8, .8])
> ax.set_xlim([-3, 3])
> ax.set_ylim([-3, 3])
>
> # a circle at the origin with radius 1
> circle = plt.Circle((0, 0), 1, transform=ax.transData,
> edgecolor='k', facecolor='none')
>
> # from Phil's example
> exterior = mpath.Path.unit_rectangle()
> interior = circle.get_path()
> exterior = mpath.Path(copy.deepcopy(exterior.vertices),
> copy.deepcopy(exterior.codes[:]))
> interior.vertices = interior.vertices[::-1]
> exterior.vertices *= 6
> exterior.vertices -= 3
> clip_path = mpath.Path(vertices=np.concatenate([exterior.vertices,
> interior.vertices]),
> codes=np.concatenate([exterior.codes,
> interior.codes]))
>
> # lines from the origin dividing the axes into 8 sectors
> end_coords = [(3, 0), (3, 3), (0, 3), (-3, 3),
> (-3, 0), (-3, -3), (0, -3), (3, -3)]
> for x, y in end_coords:
> line, = ax.plot((x, 0), (y, 0), color='k')
> line.set_clip_path(clip_path, ax.transData)
>
> ax.add_artist(circle)
>
> plt.show()
>
> and the result is the attached image with_clipping.png. You should see
> that the circle is no longer circular, and also there are weird line width
> issues. What I want it basically exactly like the attached
> without_clipping.png but with paths inside the circle removed.
>
> Thanks
>
>
>
> On 12 March 2013 16:43, Phil Elson <pel...@gm...> wrote:
>
>> You could just use paths which have holes in them, making the exterior so
>> broad that you wouldn't notice the edge of the clipping. I've put together
>> an example of doing just that:
>>
>> import matplotlib.pyplot as plt
>> import matplotlib.path as mpath
>> import matplotlib.collections as mcol
>> import numpy as np
>> import copy
>>
>>
>> exterior = mpath.Path.unit_rectangle()
>> exterior = mpath.Path(copy.deepcopy(exterior.vertices),
>> copy.deepcopy(exterior.codes[:]))
>> exterior.vertices *= 4
>> exterior.vertices -= 2
>> interior = mpath.Path.unit_circle()
>> interior.vertices = interior.vertices[::-1]
>> clip_path = mpath.Path(vertices=np.concatenate([exterior.vertices,
>> interior.vertices]),
>> codes=np.concatenate([exterior.codes,
>> interior.codes]))
>>
>> star = mpath.Path.unit_regular_star(6)
>> star.vertices *= 2.6
>>
>>
>> ax = plt.subplot(321)
>> col = mcol.PathCollection([clip_path], facecolor='yellow')
>> ax.add_collection(col)
>> ax.set_title('Clip path')
>> ax.set_xlim([-3, 3])
>> ax.set_ylim([-3, 3])
>>
>>
>> ax = plt.subplot(322)
>> col = mcol.PathCollection([star], facecolor='red')
>> ax.add_collection(col)
>> ax.set_title('Target polygon')
>> ax.set_xlim([-3, 3])
>> ax.set_ylim([-3, 3])
>>
>>
>> ax = plt.subplot2grid((3, 2), (1, 0), colspan=2, rowspan=2)
>> col = mcol.PathCollection([star])
>> col.set_clip_path(clip_path, ax.transData)
>> ax.add_collection(col)
>>
>> ax.set_title('Target polygon clipped by clip_path')
>> ax.set_xlim([-3, 3])
>> ax.set_ylim([-3, 3])
>>
>> plt.tight_layout()
>>
>> plt.show()
>>
>> [image: Inline images 1]
>>
>>
>>
>> There are other options if this doesn't cut the mustard.
>>
>> HTH,
>>
>>
>>
>>
>>
>>
>>
>> On 12 March 2013 15:37, Andrew Dawson <da...@at...> wrote:
>>
>>> Hi
>>>
>>> I'd like to be able to clip a line so that the portion of it lying
>>> outside of a given polygon remains visible and the part that lies inside of
>>> the polygon is not visible. What I want is basically the opposite of:
>>>
>>> line.set_clip_path(polygon)
>>>
>>> which leaves only the part of the line inside the polygon visible. Is
>>> this possible?
>>>
>>> I know I can just fill the polygon with the background color or
>>> something but this gets messy when there are other lines on the plot that
>>> don't need to be clipped.
>>>
>>> Thanks,
>>> Andrew
>>>
>>>
>>> ------------------------------------------------------------------------------
>>> Symantec Endpoint Protection 12 positioned as A LEADER in The Forrester
>>> Wave(TM): Endpoint Security, Q1 2013 and "remains a good choice" in the
>>> endpoint security space. For insight on selecting the right partner to
>>> tackle endpoint security challenges, access the full report.
>>> http://p.sf.net/sfu/symantec-dev2dev
>>> _______________________________________________
>>> Matplotlib-users mailing list
>>> Mat...@li...
>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>>>
>>>
>>
>
>
> --
> Dr Andrew Dawson
> Atmospheric, Oceanic & Planetary Physics
> Clarendon Laboratory
> Parks Road
> Oxford OX1 3PU, UK
> Tel: +44 (0)1865 282438
> Email: da...@at...
> Web Site: http://www2.physics.ox.ac.uk/contacts/people/dawson
>
|
|
From: Jae-Joon L. <lee...@gm...> - 2013-03-20 05:49:15
|
On Wed, Mar 13, 2013 at 2:17 AM, Andrew Dawson <da...@at...> wrote:
> You should see that the circle is no longer circular, and also there are
> weird line width issues. What I want it basically exactly like the attached
> without_clipping.png but with paths inside the circle removed.
The reason that circle is no more circle is that simply inverting the
vertices does not always results in a correctly inverted path.
Instead of following line.
interior.vertices = interior.vertices[::-1]
You should use something like below.
interior = mpath.Path(np.concatenate([interior.vertices[-2::-1],
interior.vertices[-1:]]),
interior.codes)
It would be good if we have a method to invert a path.
This will give you a circle. But the weird line width issue remains. This
seems to be an Agg issue, and the line width seems to depend on the dpi.
I guess @mdboom nay have some insight on this.
Regards,
-JJ
|
|
From: Andrew D. <da...@at...> - 2013-03-22 10:34:13
|
Thanks, the clipping is working now. But as you say the weird line width issue still remains for Agg (and png, perhaps that uses Agg, I don't know...). PDF output looks correct. On 20 March 2013 05:48, Jae-Joon Lee <lee...@gm...> wrote: > > On Wed, Mar 13, 2013 at 2:17 AM, Andrew Dawson <da...@at...>wrote: > >> You should see that the circle is no longer circular, and also there are >> weird line width issues. What I want it basically exactly like the attached >> without_clipping.png but with paths inside the circle removed. > > > The reason that circle is no more circle is that simply inverting the > vertices does not always results in a correctly inverted path. > Instead of following line. > > interior.vertices = interior.vertices[::-1] > > You should use something like below. > > interior = mpath.Path(np.concatenate([interior.vertices[-2::-1], > interior.vertices[-1:]]), > interior.codes) > > It would be good if we have a method to invert a path. > > This will give you a circle. But the weird line width issue remains. This > seems to be an Agg issue, and the line width seems to depend on the dpi. > I guess @mdboom nay have some insight on this. > > Regards, > > -JJ > > -- Dr Andrew Dawson Atmospheric, Oceanic & Planetary Physics Clarendon Laboratory Parks Road Oxford OX1 3PU, UK Tel: +44 (0)1865 282438 Email: da...@at... Web Site: http://www2.physics.ox.ac.uk/contacts/people/dawson |
|
From: Michael D. <md...@st...> - 2013-03-22 15:17:28
|
It's puzzler. I'm looking at it now. Mike On 03/22/2013 06:33 AM, Andrew Dawson wrote: > Thanks, the clipping is working now. But as you say the weird line > width issue still remains for Agg (and png, perhaps that uses Agg, I > don't know...). PDF output looks correct. > > > On 20 March 2013 05:48, Jae-Joon Lee <lee...@gm... > <mailto:lee...@gm...>> wrote: > > > On Wed, Mar 13, 2013 at 2:17 AM, Andrew Dawson > <da...@at... <mailto:da...@at...>> wrote: > > You should see that the circle is no longer circular, and also > there are weird line width issues. What I want it basically > exactly like the attached without_clipping.png but with paths > inside the circle removed. > > > The reason that circle is no more circle is that simply inverting > the vertices does not always results in a correctly inverted path. > Instead of following line. > > interior.vertices = interior.vertices[::-1] > > You should use something like below. > > interior = mpath.Path(np.concatenate([interior.vertices[-2::-1], > interior.vertices[-1:]]), > interior.codes) > > It would be good if we have a method to invert a path. > > This will give you a circle. But the weird line width issue > remains. This seems to be an Agg issue, and the line width seems > to depend on the dpi. > I guess @mdboom nay have some insight on this. > > Regards, > > -JJ > > > > > -- > Dr Andrew Dawson > Atmospheric, Oceanic & Planetary Physics > Clarendon Laboratory > Parks Road > Oxford OX1 3PU, UK > Tel: +44 (0)1865 282438 > Email: da...@at... <mailto:da...@at...> > Web Site: http://www2.physics.ox.ac.uk/contacts/people/dawson > > > ------------------------------------------------------------------------------ > Everyone hates slow websites. So do we. > Make your web apps faster with AppDynamics > Download AppDynamics Lite for free today: > http://p.sf.net/sfu/appdyn_d2d_mar > > > _______________________________________________ > Matplotlib-users mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users |
|
From: Michael D. <md...@st...> - 2013-03-22 16:40:14
|
See https://github.com/matplotlib/matplotlib/pull/1846 On 03/22/2013 11:17 AM, Michael Droettboom wrote: > It's puzzler. I'm looking at it now. > > Mike > > On 03/22/2013 06:33 AM, Andrew Dawson wrote: >> Thanks, the clipping is working now. But as you say the weird line >> width issue still remains for Agg (and png, perhaps that uses Agg, I >> don't know...). PDF output looks correct. >> >> >> On 20 March 2013 05:48, Jae-Joon Lee <lee...@gm... >> <mailto:lee...@gm...>> wrote: >> >> >> On Wed, Mar 13, 2013 at 2:17 AM, Andrew Dawson >> <da...@at... <mailto:da...@at...>> wrote: >> >> You should see that the circle is no longer circular, and >> also there are weird line width issues. What I want it >> basically exactly like the attached without_clipping.png but >> with paths inside the circle removed. >> >> >> The reason that circle is no more circle is that simply inverting >> the vertices does not always results in a correctly inverted path. >> Instead of following line. >> >> interior.vertices = interior.vertices[::-1] >> >> You should use something like below. >> >> interior = mpath.Path(np.concatenate([interior.vertices[-2::-1], >> interior.vertices[-1:]]), >> interior.codes) >> >> It would be good if we have a method to invert a path. >> >> This will give you a circle. But the weird line width issue >> remains. This seems to be an Agg issue, and the line width seems >> to depend on the dpi. >> I guess @mdboom nay have some insight on this. >> >> Regards, >> >> -JJ >> >> >> >> >> -- >> Dr Andrew Dawson >> Atmospheric, Oceanic & Planetary Physics >> Clarendon Laboratory >> Parks Road >> Oxford OX1 3PU, UK >> Tel: +44 (0)1865 282438 >> Email: da...@at... <mailto:da...@at...> >> Web Site: http://www2.physics.ox.ac.uk/contacts/people/dawson >> >> >> ------------------------------------------------------------------------------ >> Everyone hates slow websites. So do we. >> Make your web apps faster with AppDynamics >> Download AppDynamics Lite for free today: >> http://p.sf.net/sfu/appdyn_d2d_mar >> >> >> _______________________________________________ >> Matplotlib-users mailing list >> Mat...@li... >> https://lists.sourceforge.net/lists/listinfo/matplotlib-users > > > > ------------------------------------------------------------------------------ > Everyone hates slow websites. So do we. > Make your web apps faster with AppDynamics > Download AppDynamics Lite for free today: > http://p.sf.net/sfu/appdyn_d2d_mar > > > _______________________________________________ > Matplotlib-users mailing list > Mat...@li... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users |