exporting tricontour function results

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.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151130/62327bc8/attachment.html>

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
Matplotlib-users Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151130/115bee23/attachment.html&gt;

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

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
Matplotlib-users Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151201/2016acfb/attachment-0001.html&gt;
-------------- 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/20151201/2016acfb/attachment-0001.png&gt;

···

On Mon, Nov 30, 2015 at 12:46 PM, Francis Chabouis <fchabouis at gmail.com> > wrote:

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

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

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
Matplotlib-users Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151201/25a27936/attachment-0001.html&gt;
-------------- 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/20151201/25a27936/attachment-0001.png&gt;

···

On Tue, Dec 1, 2015 at 4:18 PM, Francis Chabouis <fchabouis at gmail.com> wrote:

On Mon, Nov 30, 2015 at 12:46 PM, 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 :slight_smile:

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

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

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
Matplotlib-users Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151201/4d7ebe66/attachment-0001.html&gt;
-------------- 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/20151201/4d7ebe66/attachment-0001.png&gt;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: testCase.py
Type: text/x-python
Size: 1688 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151201/4d7ebe66/attachment-0001.py&gt;

···

On Tue, Dec 1, 2015 at 4:18 PM, Francis Chabouis <fchabouis at gmail.com> > wrote:

On Mon, Nov 30, 2015 at 12:46 PM, Francis Chabouis <fchabouis 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

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 :slight_smile:

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

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

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
Matplotlib-users Info Page

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users at python.org
Matplotlib-users Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151202/22771781/attachment-0001.html&gt;
-------------- 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/22771781/attachment-0001.png&gt;

···

On 1 December 2015 at 21:57, Francis Chabouis <fchabouis at gmail.com> wrote:

On Tue, Dec 1, 2015 at 4:18 PM, Francis Chabouis <fchabouis at gmail.com> >> wrote:

On Mon, Nov 30, 2015 at 12:46 PM, Francis Chabouis <fchabouis at gmail.com >>>> > wrote:

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

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

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 :slight_smile:

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

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

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
Matplotlib-users Info Page

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users at python.org
Matplotlib-users Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151202/1d59c03d/attachment-0001.html&gt;
-------------- 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&gt;

···

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

On 1 December 2015 at 21:57, Francis Chabouis <fchabouis at gmail.com> wrote:

On Tue, Dec 1, 2015 at 4:18 PM, Francis Chabouis <fchabouis at gmail.com> >>> wrote:

On Mon, Nov 30, 2015 at 12:46 PM, Francis Chabouis < >>>>> fchabouis at gmail.com> wrote:

Thank you to both of you, it's getting clearer. I understand only now that
tricontourf is not "hiding"
some information about who is an exterior and who is an interior...it
doesn't have this information in the first place (If I get it right).
I have managed to sort all those polygons and group them correctly.
Probably not robust nor efficient, but good enough for the moment !
Cheers
Francis

2015-12-02 21:48 GMT+01:00 Benjamin Root <ben.v.root at gmail.com>:

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

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

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 :slight_smile:

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

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

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
Matplotlib-users Info Page

_______________________________________________
Matplotlib-users mailing list
Matplotlib-users at python.org
Matplotlib-users Info Page

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20151203/f0e52c68/attachment-0001.html&gt;
-------------- 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/20151203/f0e52c68/attachment-0001.png&gt;

···

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

On 1 December 2015 at 21:57, Francis Chabouis <fchabouis at gmail.com> >> wrote:

On Tue, Dec 1, 2015 at 4:18 PM, Francis Chabouis <fchabouis at gmail.com> >>>> wrote:

On Mon, Nov 30, 2015 at 12:46 PM, Francis Chabouis < >>>>>> fchabouis at gmail.com> wrote: