SourceForge logo
SourceForge logo
Menu

matplotlib-users

From: Hartmut K. <har...@gm...> - 2014年10月25日 23:18:13
All,
We try to generate contour polygons from an unstructured triangular grid
stored in a netcdf file:
 import netCDF4
 import matplotlib.tri as tri
 # read data
 var = netCDF4.Dataset('filename.cdf').variables
 x = var['x'][:]
 y = var['y'][:]
 elems = var['element'][:,:]-1
 data = var['attrname'][:] 
 # create triangulation
 triang = tri.Triangulation(x, y, triangles=elems)
 # generate contour polygons
 levels = numpy.linspace(0, maxlevel, num=numlevels)
 contour = plt.tricontourf(triang, data, levels=levels)
 # extract geometries
 for coll in contour.collections:
 # handle all geometries for one level
 for p in coll.get_paths():
 polys = p.to_polygons()
 ...
At this point we assume, that polys[0] is a linear ring to be interpreted as
a polygon exterior and polys[1:] are the corresponding interiors for
polys[0]. 
Here are our questions: 
Is this assumption correct? 
Is there any detailed documentation describing the structure of the returned
geometries? 
Are the linear rings supposed to be correctly oriented (area > 0 for
exteriors and area < 0 for the interiors)?
Thanks!
Regards Hartmut
---------------
http://boost-spirit.com
http://stellar.cct.lsu.edu
From: Ian T. <ian...@gm...> - 2014年10月26日 16:31:14
On 26 October 2014 00:18, Hartmut Kaiser <har...@gm...> wrote:
> At this point we assume, that polys[0] is a linear ring to be interpreted
> as
> a polygon exterior and polys[1:] are the corresponding interiors for
> polys[0].
>
> Here are our questions:
>
> Is this assumption correct?
> Is there any detailed documentation describing the structure of the
> returned
> geometries?
> Are the linear rings supposed to be correctly oriented (area > 0 for
> exteriors and area < 0 for the interiors)?
>
Hello Hartmut,
In brief, the answers are no, no and yes.
In more detail, assuming polys is not empty then it will contain one or
more polygon exteriors and zero or more interiors, and they can be in any
order. Here is a simple example where polys[0] is an interior and polys[1]
an exterior:
 x = [0, 0, 1, 1, 0.5]
 y = [0, 1, 0, 1, 0.5]
 z = [0.5, 0.5, 0.5, 0.5, 0]
 triang = tri.Triangulation(x, y)
 contour = plt.tricontourf(triang, z, levels=[0.2, 0.4])
The returned geometries are purposefully not documented. They are an
'implementation detail' and not considered part of the public interface.
and as such they could change at any time and hence should not be relied
upon. Of course you can choose to access them if you wish, as I do myself
sometimes, but we make no promises about what the order of the polygons is,
or that it won't change tomorrow.
In reality the order of the polygons is chosen to be something that is easy
for both the contour generation routines to create and for the various
backends to render. If you were to look at the output generated by
contourf, you will see that it is organised differently from that produced
by tricontourf and is more like you would like it to be, i.e. one or more
groups of an exterior polygon followed by zero or more interiors. This is
historical as the contourf code dates from before all of the backends were
able to render arbitrary groups of exterior and interior polygons, and so
the contourf code has to calculate the order for the backends. When the
tricontourf code was written the backends were all able to calculate the
exterior/interior containment themselves, so there was no need for
tricontourf to do it as well.
Ian
From: Hartmut K. <har...@gm...> - 2014年11月01日 18:20:59
> On 26 October 2014 00:18, Hartmut Kaiser <har...@gm...> wrote:
> At this point we assume, that polys[0] is a linear ring to be interpreted
> as
> a polygon exterior and polys[1:] are the corresponding interiors for
> polys[0].
> 
> Here are our questions:
> 
> Is this assumption correct?
> Is there any detailed documentation describing the structure of the
> returned
> geometries?
> Are the linear rings supposed to be correctly oriented (area > 0 for
> exteriors and area < 0 for the interiors)?
> 
> Hello Hartmut,
> In brief, the answers are no, no and yes.
> In more detail, assuming polys is not empty then it will contain one or
> more polygon exteriors and zero or more interiors, and they can be in any
> order. Here is a simple example where polys[0] is an interior and
> polys[1] an exterior:
> 
> x = [0, 0, 1, 1, 0.5]
> y = [0, 1, 0, 1, 0.5]
> z = [0.5, 0.5, 0.5, 0.5, 0]
> triang = tri.Triangulation(x, y)
> contour = plt.tricontourf(triang, z, levels=[0.2, 0.4])
> The returned geometries are purposefully not documented. They are an
> 'implementation detail' and not considered part of the public interface.
> and as such they could change at any time and hence should not be relied
> upon. Of course you can choose to access them if you wish, as I do myself
> sometimes, but we make no promises about what the order of the polygons
> is, or that it won't change tomorrow.
> In reality the order of the polygons is chosen to be something that is
> easy for both the contour generation routines to create and for the
> various backends to render. If you were to look at the output generated
> by contourf, you will see that it is organised differently from that
> produced by tricontourf and is more like you would like it to be, i.e. one
> or more groups of an exterior polygon followed by zero or more
> interiors. This is historical as the contourf code dates from before all
> of the backends were able to render arbitrary groups of exterior and
> interior polygons, and so the contourf code has to calculate the order for
> the backends. When the tricontourf code was written the backends were all
> able to calculate the exterior/interior containment themselves, so there
> was no need for tricontourf to do it as well.
Thanks Ian! Your detailed answer is much appreciated. 
As you might have already guessed, we have quite some problems creating clean geometries from the generated contour data. I have tried to put together one (reasonably) small test case illustrating at least one of our issues. I apologize for the lengthy code attached.
The two attached figures demonstrate what we see. Matplotlib.png (generated by the library) does not really look ok. Also, the attached shape.png shows that there are a lot of geometries generated which are self-intersecting (highlighted in dark blue), and we already skip polygons with less than 3 points. BTW, there are many polygons stacked with the same geometries. 
Anything we can do about this? 
Thanks!
Regards Hartmut
---------------
http://boost-spirit.com
http://stellar.cct.lsu.edu
From: Ian T. <ian...@gm...> - 2014年11月02日 16:10:08
On 1 November 2014 18:20, Hartmut Kaiser <har...@gm...> wrote:
> Thanks Ian! Your detailed answer is much appreciated.
>
> As you might have already guessed, we have quite some problems creating
> clean geometries from the generated contour data. I have tried to put
> together one (reasonably) small test case illustrating at least one of our
> issues. I apologize for the lengthy code attached.
>
> The two attached figures demonstrate what we see. Matplotlib.png
> (generated by the library) does not really look ok. Also, the attached
> shape.png shows that there are a lot of geometries generated which are
> self-intersecting (highlighted in dark blue), and we already skip polygons
> with less than 3 points. BTW, there are many polygons stacked with the same
> geometries.
>
> Anything we can do about this?
>
> Thanks!
> Regards Hartmut
>
Hartmut,
You are using masked arrays where you shouldn't, again. The documentation
for tricontour states that it expects z to be an array, it doesn't say
masked array. If you pass it a masked array, it will ignore the mask.
Hence you have a number of triangles that include a vertex with a z-value
of -99999; when contoured these are going to give you lots of thin polygons
that you don't want.
You need to stop using masked arrays where they are not expected. Your
triangulation should only contain triangles for which you have valid data
at all three vertices. So either remove invalid triangles from your 'ele'
array before creating the triangulation, or set a mask on the triangulation
once it has been created, e.g.
 point_mask_indices = numpy.where(z.mask)
 tri_mask = numpy.any(numpy.in1d(ele, point_mask_indices).reshape(-1,
3), axis=1)
 triang.set_mask(tri_mask)
Ian
From: Hartmut K. <har...@gm...> - 2014年11月03日 03:31:31
Ian,
> You are using masked arrays where you shouldn't, again. The documentation
> for tricontour states that it expects z to be an array, it doesn't say
> masked array. If you pass it a masked array, it will ignore the
> mask. Hence you have a number of triangles that include a vertex with a
> z-value of -99999; when contoured these are going to give you lots of thin
> polygons that you don't want.
> You need to stop using masked arrays where they are not expected. Your
> triangulation should only contain triangles for which you have valid data
> at all three vertices. So either remove invalid triangles from your 'ele'
> array before creating the triangulation, or set a mask on the
> triangulation once it has been created, e.g.
> 
> point_mask_indices = numpy.where(z.mask)
> tri_mask = numpy.any(numpy.in1d(ele, point_mask_indices).reshape(-1,
> 3), axis=1)
> triang.set_mask(tri_mask)
Thanks very much for this explanation! With your code everything fell into place and we see the geometries we expect to see. Great library!
Regards Hartmut
---------------
http://boost-spirit.com
http://stellar.cct.lsu.edu
From: Benjamin R. <ben...@ou...> - 2014年11月02日 16:30:52
Would it make sense to at least emit a warning when a mask is encountered.
There are very few places in matplotlib where masked arrays are not allowed
(I think histograms is the other spot, but I can't remember for sure).
On Sun, Nov 2, 2014 at 11:10 AM, Ian Thomas <ian...@gm...> wrote:
> On 1 November 2014 18:20, Hartmut Kaiser <har...@gm...> wrote:
>
>> Thanks Ian! Your detailed answer is much appreciated.
>>
>> As you might have already guessed, we have quite some problems creating
>> clean geometries from the generated contour data. I have tried to put
>> together one (reasonably) small test case illustrating at least one of our
>> issues. I apologize for the lengthy code attached.
>>
>> The two attached figures demonstrate what we see. Matplotlib.png
>> (generated by the library) does not really look ok. Also, the attached
>> shape.png shows that there are a lot of geometries generated which are
>> self-intersecting (highlighted in dark blue), and we already skip polygons
>> with less than 3 points. BTW, there are many polygons stacked with the same
>> geometries.
>>
>> Anything we can do about this?
>>
>> Thanks!
>> Regards Hartmut
>>
>
> Hartmut,
>
> You are using masked arrays where you shouldn't, again. The documentation
> for tricontour states that it expects z to be an array, it doesn't say
> masked array. If you pass it a masked array, it will ignore the mask.
> Hence you have a number of triangles that include a vertex with a z-value
> of -99999; when contoured these are going to give you lots of thin polygons
> that you don't want.
>
> You need to stop using masked arrays where they are not expected. Your
> triangulation should only contain triangles for which you have valid data
> at all three vertices. So either remove invalid triangles from your 'ele'
> array before creating the triangulation, or set a mask on the triangulation
> once it has been created, e.g.
>
> point_mask_indices = numpy.where(z.mask)
> tri_mask = numpy.any(numpy.in1d(ele, point_mask_indices).reshape(-1,
> 3), axis=1)
> triang.set_mask(tri_mask)
>
> Ian
>
>
> ------------------------------------------------------------------------------
>
> _______________________________________________
> Matplotlib-users mailing list
> Mat...@li...
> https://lists.sourceforge.net/lists/listinfo/matplotlib-users
>
>
From: Ian T. <ian...@gm...> - 2014年11月04日 08:14:46
On 2 November 2014 16:30, Benjamin Root <ben...@ou...> wrote:
> Would it make sense to at least emit a warning when a mask is encountered.
> There are very few places in matplotlib where masked arrays are not allowed
> (I think histograms is the other spot, but I can't remember for sure).
>
Ben,
That's certainly an option, but I'm happy with leaving it as it is with the
onus on users to read the documentation.
Ian
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.
Thanks for helping keep SourceForge clean.
X





Briefly describe the problem (required):
Upload screenshot of ad (required):
Select a file, or drag & drop file here.
Screenshot instructions:

Click URL instructions:
Right-click on the ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies

Ad destination/click URL:

AltStyle によって変換されたページ (->オリジナル) /