[Matplotlib-users] exporting tricontour function results

Benjamin Root ben.v.root at gmail.com
Wed Dec 2 15:48:16 EST 2015


Ian,

I see now how tricontourf()'s polygons are fundamentally different from
contourf()'s polygons (and explains the discrepancy the user is seeing),
and I see I misread your comments. That said, any sort of modification that
would change the output of to_polygons() in a substantial way would
certainly need major justification. The functions have been there for a
long time and people have come to expect them to behave in a certain way.

Ben Root


On Wed, Dec 2, 2015 at 3:00 PM, Ian Thomas <ianthomas23 at gmail.com> wrote:

> Francis,
>
> Your question about interior and exterior polygons is already answered in
> the thread you keep referring to.  I'll repeat it here.  tricontouf does
> not return any information about which interior polygons are located inside
> which exterior polygons.  All you get is a collection of polygons, composed
> of one or more exteriors and zero or more interiors, and they can be in any
> order.  The backends take these arbitrary collections of exterior and
> interior polygons and render them correctly.  As all of the backends are
> capable of calculating the exterior/interior containment themselves, there
> is no need for tricontourf to do it as well.
>
> contourf produces different output, grouping each exterior polygon with
> its contained interior polygons.  This is because it dates from before all
> the backends were capable of calculating polygon containment, so contourf
> had to do it.  The recent rewrite of the contourf C++ code still does this
> so that it produces output consistent with the legacy code.
>
> If you want take the output of tricontourf and calculate the
> exterior/interior containment, you'll either have to find some other
> library to do it, or write the code yourself.  I have not looked into
> libraries that do this as I do not need this functionality.  Writing the
> code to do it yourself is pretty easy, but making it robust and efficient
> is much harder.
>
> Ben,
>
> I think you have misunderstood my comments from last year.  When I was
> talking about what I consider private, I was referring to the segs and
> kinds that are passed from C++ to python to make up the various Path
> objects.  I didn't refer to the function to_polygons() being private, in
> fact I didn't refer to it at all.
>
> Ian
>
> On 1 December 2015 at 21:57, Francis Chabouis <fchabouis at gmail.com> wrote:
>
>> Ben,
>>
>> 1. Exporting data like this was never an intended use => I understand
>> your point. In fact if calling the underlying C++ code for tricontour had
>> been easy I would happily have skipped the call to MPL. All I'm interested
>> in is the polygons coordinates really.
>>
>> 2. good news :)
>>
>> 3. please find the script attached.
>>
>> thanks
>> Francis
>>
>> 2015-12-01 22:33 GMT+01:00 Benjamin Root <ben.v.root at gmail.com>:
>>
>>> Francis,
>>>
>>> 1. Keep in mind, matplotlib is a plotting library first. Path
>>> simplification takes into account the resolution of the output device when
>>> used for drawing and essentially simplifies out any unresolvable features,
>>> which greatly reduces drawing time for complex plots. Exporting data like
>>> this was never an intended use.
>>>
>>> 2. I will have to respectfully disagree with Ian on this point.
>>> to_polygons() is not a private method and it is perfectly reasonable to
>>> expect it to be used by people outside the matplotlib codebase. As a
>>> developer, I would reject any patches that changes the output semantics of
>>> to_polygons() without going through a lengthy deprecation cycle. Plus, the
>>> primary use of this method is for easy input to Polygon artist objects,
>>> which has a constructor that isn't going to change, so why should
>>> to_polygons() change?
>>>
>>> 3. Without the source example data, I am at a bit of a loss for what is
>>> happening here. I could come up with all sorts of guesses, but I can't tell
>>> you for sure without having something I can run myself.
>>>
>>> Cheers!
>>> Ben Root
>>>
>>>
>>> On Tue, Dec 1, 2015 at 4:18 PM, Francis Chabouis <fchabouis at gmail.com>
>>> wrote:
>>>
>>>> Thanks Ben for your answer.
>>>>
>>>> I didn't know about that should_simplify attribute. It was effectively
>>>> the reason for the disappearing points. Thanks a lot.
>>>> I still have a few questions if you don't mind :
>>>>
>>>> 1. [low importance] Isn't it weird to have this attribute set to True
>>>> by default ? I would find it  more natural if simplification had to be
>>>> explicitly requested.
>>>>
>>>> 2. You say "The first element of that list is the external vertexes,
>>>> and the rest of the elements are all vertex lists of the internal holes." I
>>>> like this a lot, but are you sure it is true ? As it comes in contradiction
>>>> with Ian Thomas explanation :
>>>>
>>>> "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."
>>>>
>>>>
>>>> http://matplotlib.1069221.n5.nabble.com/Structure-of-contour-object-returned-from-tricontourf-td44203.html
>>>>
>>>> 3. I have done a simple test and the output looks like this (2 rings):
>>>>
>>>> [image: Images intégrées 1]
>>>>
>>>> So I'm a bit confused as :
>>>>
>>>> cs = plt.tricontourf(t, v, levels)
>>>> #cs.collections has 1 element (ok as there is only one level)
>>>>
>>>> for i,collection in enumerate(cs.collections):
>>>>     for path in collection.get_paths():
>>>>     #collection.get_paths() has only 1 element, I would eventually have
>>>> expected 2 (1 for each ring)
>>>>     polygons = path.to_polygons()
>>>>     # polygons has 4 elements : the 4 rings are stored at the same place
>>>>     # how can I recognise the exteriors from the interiors ?
>>>>
>>>> Thanks for your help,
>>>> Francis
>>>>
>>>>
>>>>
>>>> 2015-11-30 19:37 GMT+01:00 Benjamin Root <ben.v.root at gmail.com>:
>>>>
>>>>> Francis,
>>>>>
>>>>> I bet you that the inconsistency in the number of vertexes is due to
>>>>> path simplification. The list of Path objects you get when you call
>>>>> get_paths() on the collection object each have an attribute
>>>>> "should_simplify" and that defaults to True. Set it to False, and you will
>>>>> have all of the vertexes. Also, what you want to call is to_polygons() on
>>>>> the Path object after setting "should_simplify" to False. That will return
>>>>> a list of lists. The first element of that list is the external vertexes,
>>>>> and the rest of the elements are all vertex lists of the internal holes.
>>>>>
>>>>> I hope this description helps. I can't really give you more detailed
>>>>> description due to the fact that I have developed software that does this
>>>>> very thing for my employer, but what you want is certainly possible.
>>>>>
>>>>> Also, as for whether or not we would want a geojson export function
>>>>> available for matplotlib, it isn't really correct to have it in matplotlib
>>>>> because we are a graphing library. However, it would make sense to make the
>>>>> process of extracting the polygon information a bit easier, which would
>>>>> make it easier for another package to be made that would export that
>>>>> information into various data formats, not just geojson.
>>>>>
>>>>> Cheers!
>>>>> Ben Root
>>>>>
>>>>>
>>>>> On Mon, Nov 30, 2015 at 12:46 PM, Francis Chabouis <
>>>>> fchabouis at gmail.com> wrote:
>>>>>
>>>>>> Hello,
>>>>>> I'm having some difficulties with the results of the tricontour
>>>>>> function. What I'm trying to achieve is fairly simple : I'd like to export
>>>>>> the results of the tricontour function as a geoJson. (I think a function
>>>>>> doing exactly this job would be nice to have in the library).
>>>>>>
>>>>>> I wrote this :
>>>>>>
>>>>>> cs = plt.tricontourf(t, v, levels)
>>>>>>
>>>>>> for i,collection in enumerate(cs.collections):
>>>>>>     for path in collection.get_paths():
>>>>>>
>>>>>>
>>>>>> Now I have this path object.
>>>>>>
>>>>>> My first problem : when I check the number of vertices (via
>>>>>> len(path.vertices)) I get 732 vertices.
>>>>>> If I try to access those vertices with iter_segments as recommended
>>>>>> in the doc, I get only 125 vertices.
>>>>>> seg = path.iter_segments()
>>>>>> print len(list(seg))
>>>>>> ==> 125
>>>>>>
>>>>>> Am I doing something wrong, or is it possibly a bug ?
>>>>>>
>>>>>> My second problem : geoJson works with interior and exterior rings.
>>>>>> To describe a polygon with a hole in it, we first declare a closed line
>>>>>> (that will be the exterior) and all the subsequent lines will be the
>>>>>> "holes" (interiors). It seems that what I get from iter_segments and
>>>>>> to_polygons is a bunch of lines, but there is no way to know which is an
>>>>>> interior, which is an exterior. But I guess this must be stored somewhere
>>>>>> as MPL is able to draw a graph from this information !
>>>>>>
>>>>>> Any hints on how I should proceed ?
>>>>>> Let me know if you need additional information.
>>>>>>
>>>>>> Thanks
>>>>>>
>>>>>> ps : I got some of my infos from this thread :
>>>>>> http://matplotlib.1069221.n5.nabble.com/Structure-of-contour-object-returned-from-tricontourf-td44203.html
>>>>>>
>>>>>> ps2 : If I can write this function I would be happy to integrate it
>>>>>> in the lib if you're interested.
>>>>>>
>>>>>> _______________________________________________
>>>>>> Matplotlib-users mailing list
>>>>>> Matplotlib-users at python.org
>>>>>> https://mail.python.org/mailman/listinfo/matplotlib-users
>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
>> _______________________________________________
>> Matplotlib-users mailing list
>> Matplotlib-users at python.org
>> https://mail.python.org/mailman/listinfo/matplotlib-users
>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151202/1d59c03d/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: image.png
Type: image/png
Size: 26890 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151202/1d59c03d/attachment-0001.png>


More information about the Matplotlib-users mailing list