How to add a basemap to a 3D surface plot

Dear colleagues,
Wonder if there is a solution for prejecting
a basemap, in my task, its a river shapefile, onto a 3D surface plot using
Matplotlib.
I’ve tried to use the Axes3D.ax.add_collection3d(rivers)
method but my test did throw an error message like this.

tentatively add basemap to 3D

m = Basemap(llcrnrlon=llclon,llcrnrlat=llclat,urcrnrlon=urclon,urcrnrlat=urclat,
resolution =‘l’,area_thresh=1000.)
river4 = m.readshapefile(’…/maps/KEN_water_lines_dcw’,‘rivers4’,drawbounds=True,color=‘SlateBlue’,
linewidth=1)
ax.add_collection3d(river4)
Error thrown at the add_collection3d
is: AttributeError: 'tuple' object has no attribute 'set_label'.
Any hints or references to a similar
example code are welcome.
Regards,
Claude

···

**
Claude Falbriard
Certified IT Specialist L2 - Middleware
AMS Hortolândia / SP - Brazil
phone: +55 13 9 9760 0453
cell: +55 13 9 8117 3316
e-mail: claudef@…3779…**

From the docstring for readshapefile:

A tuple (num_shapes, type, min, max) containing shape file info
is returned.
num_shapes is the number of shapes, type is the type code (one of

the SHPT* constants defined in the shapelib module, see
[http://shapelib.maptools.org/shp_api.html](http://shapelib.maptools.org/shp_api.html)) and min and
max are 4-element lists with the minimum and maximum values of the

vertices. If ``drawbounds=True`` a
matplotlib.patches.LineCollection object is appended to the tuple.

So, you are trying to add the tuple result rather than the line collection that you have. That said, because readshapefile draws to an axes anyway, it should already be adding the collection to the axes anyway. Try printing out the type of the last element of the returned tuple. It should say that it is a Line3DCollection type, because the Axes3D object should be converting collections upon being added internally.

I should also note that at this time, mplot3d only supports linear projections (I am currently working on a fix to support non-linear projections, but it is still limited to rectilinear coordinates). Also, I have never actually tried mashing together basemap and mplot3d, so if this works, let me know!

Cheers!
Ben Root

···

On Thu, Jul 17, 2014 at 8:22 AM, <claudef@…713…779…> wrote:

Dear colleagues,
Wonder if there is a solution for prejecting
a basemap, in my task, its a river shapefile, onto a 3D surface plot using
Matplotlib.
I’ve tried to use the Axes3D.ax.add_collection3d(rivers)
method but my test did throw an error message like this.

tentatively add basemap to 3D

m = Basemap(llcrnrlon=llclon,llcrnrlat=llclat,urcrnrlon=urclon,urcrnrlat=urclat,
resolution =‘l’,area_thresh=1000.)
river4 = m.readshapefile(’…/maps/KEN_water_lines_dcw’,‘rivers4’,drawbounds=True,color=‘SlateBlue’,
linewidth=1)
ax.add_collection3d(river4)
Error thrown at the add_collection3d
is: AttributeError: 'tuple' object has no attribute 'set_label'.
Any hints or references to a similar
example code are welcome.
Regards,
Claude
**
Claude Falbriard
Certified IT Specialist L2 - Middleware
AMS Hortolândia / SP - Brazil
phone: +55 13 9 9760 0453
cell: +55 13 9 8117 3316
e-mail: claudef@…3779…**

Want fast and easy access to all the code in your enterprise? Index and

search up to 200,000 lines of code with a free copy of Black Duck

Code Sight - the same software that powers the world’s largest code

search on Ohloh, the Black Duck Open Hub! Try it now.

http://p.sf.net/sfu/bds


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users

Dear Ben,
Thanks for the hints. Yes, indeed I
was able to print the tuple and loaded the LineCollection (from the basemap
shapefile) through my code, a solution that stopped the error (set_label)
described below:
Here the tuple (river4, Observe the
LineCollection is a2D object):
(2569, 3, [33.953826960934919, -4.6502805036029002,
0.0, 0.0], [41.853908604641568, 4.6249956275413666, 0.0, 0.0], <matplotlib.collections.LineCollection
object at 0x4b9a5d0>)
# tentatively add basemap to 3D
m = Basemap(llcrnrlon=llclon,llcrnrlat=llclat,urcrnrlon=urclon,urcrnrlat=urclat, resolution ='l',area_thresh=1000.)
river4 = m.readshapefile('../maps/KEN_water_lines_dcw','rivers4',drawbounds=True,color='SlateBlue', linewidth=1)
# scan though shapefile collection
for entry in river4:
if str(type(entry).__name__) == 'LineCollection':
lineCollection = entry
ax.add_collection3d(lineCollection)
It even projects now the rivers over
the 3D grid axes, but it did not merge it onto the surface plot, indeed
it hided the surface plot drawing and now just displays the lines.
Are there any further commands required
to project the the LineCollection (rivers) over the plot_surface (terrain).
Looks like a solution is close.
Thanks in advance for any hint.
Regards,
Claude

···

**
Claude Falbriard
Certified IT Specialist L2 - Middleware
AMS Hortolândia / SP - Brazil
phone: +55 13 9 9760 0453
cell: +55 13 9 8117 3316
e-mail: claudef@…3779…**

From:
Benjamin Root <ben.root@…1304…>

To:
falbriard <claudef@…3729…79…>,

Cc:
Matplotlib Users matplotlib-users@lists.sourceforge.net

Date:
17/07/2014 10:49

Subject:
Re: [Matplotlib-users]
How to add a basemap to a 3D surface plot

Sent by:
ben.v.root@…287…


From the docstring for readshapefile:
A tuple (num_shapes, type, min, max) containing shape file info
is returned.
num_shapes is the number of shapes, type is the type
code (one of
the SHPT* constants defined in the shapelib module,
see
http://shapelib.maptools.org/shp_api.html)
and min and
max are 4-element lists with the minimum and maximum
values of the
vertices. If drawbounds=True a
matplotlib.patches.LineCollection object is appended
to the tuple.
So, you are trying to add the tuple result rather than
the line collection that you have. That said, because readshapefile draws
to an axes anyway, it should already be adding the collection to the axes
anyway. Try printing out the type of the last element of the returned tuple.
It should say that it is a Line3DCollection type, because the Axes3D object
should be converting collections upon being added internally.
I should also note that at this time, mplot3d only supports
linear projections (I am currently working on a fix to support non-linear
projections, but it is still limited to rectilinear coordinates). Also,
I have never actually tried mashing together basemap and mplot3d, so if
this works, let me know!
Cheers!
Ben Root
On Thu, Jul 17, 2014 at 8:22 AM, <claudef@…3779…> wrote:
Dear colleagues,
Wonder if there is a solution for prejecting a basemap, in my task, its
a river shapefile, onto a 3D surface plot using Matplotlib.
I’ve tried to use the Axes3D.ax.add_collection3d(rivers) method but my
test did throw an error message like this.

tentatively add basemap to 3D

m = Basemap(llcrnrlon=llclon,llcrnrlat=llclat,urcrnrlon=urclon,urcrnrlat=urclat,
resolution =‘l’,area_thresh=1000.)
river4 = m.readshapefile(’…/maps/KEN_water_lines_dcw’,‘rivers4’,drawbounds=True,color=‘SlateBlue’,
linewidth=1)
ax.add_collection3d(river4)
Error thrown at the add_collection3d is: AttributeError: 'tuple' object has no attribute 'set_label'.
Any hints or references to a similar example code are welcome.
Regards,
Claude
**
Claude Falbriard
Certified IT Specialist L2 - Middleware
AMS Hortolândia / SP - Brazil
phone: +55
13 9 9760 0453

cell: ** +55
13 9 8117 3316
**
e-mail: **claudef@…4509…


Want fast and easy access to all the code in your enterprise? Index and

search up to 200,000 lines of code with a free copy of Black Duck

Code Sight - the same software that powers the world’s largest code

search on Ohloh, the Black Duck Open Hub! Try it now.

http://p.sf.net/sfu/bds


Matplotlib-users mailing list

Matplotlib-users@lists.sourceforge.net

https://lists.sourceforge.net/lists/listinfo/matplotlib-users