I have been trying to plot Exclusive Economic Zone (EEZ) shapefiles on an orthographic projection from the basemap package. However, the shapefile file has EEZs from around the world, and so when I try to plot the shapefiles there are always some that are not visible in the projection at that particular angle. This results in the shapes being smeared out, which is not quite the effect that I am going for. Ultimately I wish to only plot select shapefiles, but then this same issue will likely pop up so for now I'd be happy to solve this more basic case where I try to plot all of them.
Here in the code I try a simple case where I plot the shapefiles with the readshapefile command from basemap. I have also tried plotting the various shapes as polygons (figured that would give me more flexibility in changing the appearances of the individual shapefiles) but then I could not get the polygons to appear on the map in the right spot and I would see similar smearing behavior (so likely the issue has the same or a similar root cause).
I have attached the code from the simple case below. If I run this, I get the projection to appear as a I want, but with the smearing of the shapefiles. The shapefiles can be found at http://www.marineregions.org/downloads.php#unioneezcountry where I use version 2 of Marine and land zones: the union of world country boundaries and EEZ's.
#Here is the figure
fig=plt.figure(figsize=(20,12))
ax=fig.add_subplot(111)
#create the map projection
Map=Basemap(projection='ortho',lon_0=0,lat_0=0,resolution='l')
Map.drawcoastlines(zorder=10)
Map.drawcountries(zorder=10)
Map.drawmapboundary()
#Reading in the shapefile and plotting it
Map.readshapefile('~/EEZ_Boundaries/EEZ_land_v2_201410','countries')
Here is a link to the image I get when I run the code
Ok, so after more time of trying to get this to work, I have pretty much given up with Basemap and made a (long overdue) switch to cartopy. In that case, the problem does solved by Cartopy already, so the code that creates the figure I was trying to get is:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.feature as cpf
from cartopy.io.shapereader import Reader
#Set the projection
projection=ccrs.Orthographic(central_longitude=0,central_latitude=0)
fig=plt.figure(figsize=(20,12))
axMap=fig.add_subplot(1,1,1,projection=projection)
#resolution of the coastlines
resolution='10m'
axMap.coastlines(resolution=resolution,edgecolor='black',zorder=10)
#Add the shapefiles
shape_feature = cpf.ShapelyFeature(Reader(direc_shp+file_shp).geometries(),
ccrs.PlateCarree(), edgecolor='black')
axMap.add_feature(shape_feature,zorder=1)
Related
For my team project I'm trying to obtain a map of my city using Python and plot a heatmap on it. I'm using Basemap and matplotlib.
I found that selecting epsg=3003 gives sufficient graphic results, but the problem is that if I want to visualize a precise coordinate on the map, for example lat=45.0306 and long=7.42, it shows a different point with respect to the one I get with Google Earth.
Since I need to plot data with very precise and near coordinates, getting an accurate map is essential.
Can anyone help me with my code?
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import numpy as np
map = Basemap(llcrnrlat=45,urcrnrlat=45.4,
llcrnrlon=7.41,urcrnrlon=7.8,resolution='h', epsg=3003)
map.arcgisimage(service='ESRI_StreetMap_World_2D', xpixels = 3000, verbose= True)
plt.show()
The problem is that you are using two different projection systems. Google Earth uses WGS84, whose epsg code is: 3857 but you set up your map using EPSG:3003. The best would simply be to change the projection of your map when you define your basemap. Alternatively, if you really want to use EPSG:3003 then you have to reproject the coordinate you get from Google Earth (you may want to have a look at this answer)
Here a small example to show that by using the proper projection you can nicely match google map results:
map = Basemap(llcrnrlat=45.245,urcrnrlat=45.255,
llcrnrlon=7.54,urcrnrlon=7.55,resolution='h', epsg=4326)
map.arcgisimage(service='ESRI_StreetMap_World_2D', xpixels = 3000, verbose= True)
plt.plot(7.544335,45.250423,marker='+',markersize=15,color='Red')
Here the map from basemap with a google map screenshot:
I would like to load an STL file and produce a set of 2D images in different rotations.
I got the basics working with numpy-stl based on this example, ended up with this code -
from stl import mesh
from mpl_toolkits import mplot3d
from matplotlib import pyplot
filename = '3001.stl'
# Create a new plot
figure = pyplot.figure()
axes = figure.gca(projection='3d')
# Load the STL files and add the vectors to the plot
mesh = mesh.Mesh.from_file(filename)
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(mesh.vectors, color='lightgrey'))
#axes.plot_surface(mesh.x,mesh.y,mesh.z)
# Auto scale to the mesh size
scale = mesh.points.flatten()
axes.auto_scale_xyz(scale, scale, scale)
#turn off grid and axis from display
pyplot.axis('off')
#set viewing angle
axes.view_init(azim=120)
# Show the plot to the screen
pyplot.show()
This works well only that I end up with a silhouette of the component, lacking a lot of the detail. the picture below is a lego brick...
I tried to highlight the edges. but that is sensitive to how the model was created, which is not great for me.
I was hoping that by adding lighting, the shadows could help add the missing detail but I can't find a way to do that.
Any idea how to add lightsource to the code below to create shadows ?
After getting tired with Mayavi's install disasters I ended up writing my own library for this.
https://github.com/bwoodsend/vtkplotlib
Your code would be something like
import vtkplotlib as vpl
from stl.mesh import Mesh
path = "your path here.stl"
# Read the STL using numpy-stl
mesh = Mesh.from_file(path)
# Plot the mesh
vpl.mesh_plot(mesh)
# Show the figure
vpl.show()
If you want the brick to be blue you can replace the mesh_plot with
vpl.mesh_plot(mesh, color="blue")
If you don't find Mayavi helpful, you could try Panda3D which is intended for graphics/3D rendering applications. I find it quite straightforward for doing simple stuff like this.
I have a shapefile that I have downloaded onto my local hard drive. I can use Cartopy to read the shapefile and plot a map using Matplotlib as follows:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
reader = shpreader.Reader('/path_to_shapefile/myShapeFile.shp')
ax = plt.axes(projection=ccrs.OSGB())
ax.add_geometries(reader.geometries(),ccrs.OSGB(),edgecolor = 'k',facecolor = 'none')
plt.show()
However, I would like to be able to identify the geographic co-ordinate system of the shapefile (e.g. WGS84 or OSGB) so that I can make sure that it matches the co-ordinate values of some points that I want to plot on the same map. Having read the shapefile, I assume that Cartopy can display the coordinate system used but I can't find out how to do so. Can Cartopy do this or do I need to use a different package?
Cartopy is using pyshp under the hood to read the shapefile. As far as I can tell, that library does not provide the information you are looking for. (CartoPy does not expose this information about PyShp anyway.)
Your best bet may be to look at Fiona, which are nice Python bindings for GDAL. You could use this to open the shapefile manually and inspect--I assume this library will provide the information you're looking for, if anything in the Python space does.
I have been following instructions from user pelson to create a map with filled country shapes. (Fill countries in python basemap)
Now I was curious on putting this one step further and creating a html site like this:
http://www.ethnologue.com/region/NEU
I don't need those fancy popups but those links (http://www.w3schools.com/tags/att_area_href.asp) for every country would be real nice.
Is it possible to create those lists of coordinates with cartopy?
I'm looking for a fully automatic script generating a static html file.
Yes, this is definitely possible, but if you're producing web based maps, it might be worth you looking at D3.js (specifically, for maps see this excellent tutorial http://bost.ocks.org/mike/map/).
For cartopy however I'll take this through step-by-step, as it is a good walkthrough of the transformation system in matplotlib and cartopy.
First, we can get the pixel coordinate of any point in a figure:
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
ax = plt.axes(projection=ccrs.PlateCarree())
ax.set_global()
ax.coastlines()
# Define a transformation which takes latitude and longitude values,
# and returns pixel coordinates.
ll_to_pixel = ccrs.Geodetic()._as_mpl_transform(ax)
# We need to call draw to ensure that the axes location has been defined
# fully.
plt.draw()
# Now lets figure out the pixel coordinate of Sydney.
x_pix, y_pix = ll_to_pixel.transform_point([151.2111, -33.8600])
# We can even plot these pixel coordinates directly with matplotlib.
plt.plot(x_pix, y_pix, 'ob', markersize=25, transform=None)
plt.savefig('figure_1.png', dpi=plt.gcf().get_dpi())
plt.show()
Now we have the information necessary to write the code to produce the area map, which I've gone ahead and written with full comments (<80 lines). I've posted this as a gist (https://gist.github.com/pelson/6308997) so that you can check it out and give it a go, if you like. For a live demo of the result: https://rawgithub.com/pelson/6308997/raw/map.html
Is it possible to plot contours over a polar stereographic map with the latest version of cartopy?
I'd like to see an example of how this is done as I'm struggling to work it out myself!
The stereographic projection is causing a couple of headaches and is probably the projection which has raised the most issues for cartopy's polygon transformations code.
The following example show how one should produce a polar stereographic plot with cartopy.
Please note: even with this code, it is possible to tweak the sample data resolution and find that the plot takes ~30 minutes to actually render (that is a bug which we will need to sort sooner rather than later).
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
from cartopy.examples.waves import sample_data
ax = plt.axes(projection=ccrs.NorthPolarStereo())
x, y, z = sample_data((100, 200))
cs = ax.contourf(x, y, z, 50,
transform=ccrs.PlateCarree(),
cmap='gist_ncar')
ax.coastlines()
# without the set_global, currently, the plot is tiny because the limits
# are being erroneously being set (opened issue for that)
ax.set_global()
plt.show()
Hopefully that will show you how one should make a polar stereographic contour plot in cartopy. If you having problems with your data have a look at the open issues tagged "Geometry transforms" and see if you are getting something similar, if not, go ahead and open an issue and we can look into it.
Note: This answer is relating to cartopy v0.5.x (i.e. just before a v0.5 release), and many of the bugs mentioned here should hopefully be squashed in future releases.
Hope that helps,