Dynamic Visualisation of Global Plots - python

I have produced 17 global plots that show the decadal averages in maximum surface ozone from 1850-2015. Rather than plotting them individually, I wish to create an animation that cycles through them (almost like a gif), i.e. have the same coastlines, axes and colour bar throughout but change what is being plotted as the contour.
Any help on how to adapt my code to do this would be greatly appreciated - thank you in advance!!
import numpy as np
import netCDF4 as n4
import matplotlib.pyplot as plt
from matplotlib import colorbar, colors
import matplotlib.cm as cm
import cartopy as cart
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import cartopy.feature as cfeature
nc = n4.Dataset('datafile.nc','r')
# daily maximum O3 VMR (units: mol mol-1)
sfo3max = nc.variables['sfo3max']
lon = nc.variables['lon'] # longitude
lat = nc.variables['lat'] # latitude
# (I manipulate the data to produce 17 arrays containing the decadal average O3 VMR which are
# listed below in sfo3max_avg)
sfo3max_avg = [sfo3max_1850_1860_avg, sfo3max_1860_1870_avg, sfo3max_1870_1880_avg,
sfo3max_1880_1890_avg, sfo3max_1890_1900_avg, sfo3max_1900_1910_avg,
sfo3max_1910_1920_avg, sfo3max_1920_1930_avg, sfo3max_1930_1940_avg,
sfo3max_1940_1950_avg, sfo3max_1950_1960_avg, sfo3max_1960_1970_avg,
sfo3max_1970_1980_avg, sfo3max_1980_1990_avg, sfo3max_1990_2000_avg,
sfo3max_2000_2010_avg, sfo3max_2010_2015_avg]
# find overall min & max values for colour bar in plots
min_sfo3max_avg = np.array([])
for i in sfo3max_avg:
sfo3max_avg_min = np.amin(i)
min_sfo3max_avg = np.append(min_sfo3max_avg, sfo3max_avg_min)
overall_min_sfo3max_avg = np.amin(min_sfo3max_avg)
max_sfo3max_avg = np.array([])
for i in sfo3max_avg:
sfo3max_avg_max = np.amax(i)
max_sfo3max_avg = np.append(max_sfo3max_avg, sfo3max_avg_max)
overall_max_sfo3max_avg = np.amax(max_sfo3max_avg)
# finally plot the 17 global plots of sfo3max_avg
for k in sfo3max_avg:
fig = plt.figure()
ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines() # Adding coastlines
cs = ax.contourf(lon[:], lat[:], k[:], cmap='magma')
ax.set_title('Decadal Average of Maximum O3 Volume Mixing Ratio')
m = plt.cm.ScalarMappable(cmap=cm.magma)
m.set_array(i[:])
m.set_clim(overall_min_sfo3max_avg, overall_max_sfo3max_avg)
# Additional necessary information
cbar = plt.colorbar(m, boundaries=np.arange(overall_min_sfo3max_avg, overall_max_sfo3max_avg
+ 0.5e-08, 0.5e-08))
cbar.set_label('mol mol-1')
# Adding axis labels - latitude & longitude
gridl = ax.gridlines(color="black", linestyle="dotted", draw_labels=True)
gridl.xformatter=LONGITUDE_FORMATTER
gridl.yformatter=LATITUDE_FORMATTER
gridl.xlabels_top = False
gridl.ylabels_right = False
fig.set_size_inches(w=20,h=10)
plt.show() # show global plot

Several elements in your plotting can be kept out of the loop because they only need to be set up once. After you set up the plot elements you can update the plot and animate by looping over the list. This can be achieved by making use of matplotlib's interactive mode as shown in the code below:
import numpy as np
import netCDF4 as n4
import matplotlib
matplotlib.use("nbagg")
import matplotlib.pyplot as plt
from matplotlib import colorbar, colors
import matplotlib.cm as cm
import cartopy as cart
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
import cartopy.feature as cfeature
nc = n4.Dataset('datafile.nc','r')
# daily maximum O3 VMR (units: mol mol-1)
sfo3max = nc.variables['sfo3max']
lon = nc.variables['lon'] # longitude
lat = nc.variables['lat'] # latitude
# (I manipulate the data to produce 17 arrays containing the decadal average O3 VMR which are
# listed below in sfo3max_avg)
sfo3max_avg = [sfo3max_1850_1860_avg, sfo3max_1860_1870_avg, sfo3max_1870_1880_avg,
sfo3max_1880_1890_avg, sfo3max_1890_1900_avg, sfo3max_1900_1910_avg,
sfo3max_1910_1920_avg, sfo3max_1920_1930_avg, sfo3max_1930_1940_avg,
sfo3max_1940_1950_avg, sfo3max_1950_1960_avg, sfo3max_1960_1970_avg,
sfo3max_1970_1980_avg, sfo3max_1980_1990_avg, sfo3max_1990_2000_avg,
sfo3max_2000_2010_avg, sfo3max_2010_2015_avg]
# find overall min & max values for colour bar in plots
min_sfo3max_avg = np.array([])
for i in sfo3max_avg:
sfo3max_avg_min = np.amin(i)
min_sfo3max_avg = np.append(min_sfo3max_avg, sfo3max_avg_min)
overall_min_sfo3max_avg = np.amin(min_sfo3max_avg)
max_sfo3max_avg = np.array([])
for i in sfo3max_avg:
sfo3max_avg_max = np.amax(i)
max_sfo3max_avg = np.append(max_sfo3max_avg, sfo3max_avg_max)
overall_max_sfo3max_avg = np.amax(max_sfo3max_avg)
#setup the plot elements
fig = plt.figure()
fig.set_size_inches(w=20,h=10)
ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines() # Adding coastlines
ax.set_title('Decadal Average of Maximum O3 Volume Mixing Ratio')
m = plt.cm.ScalarMappable(cmap=cm.magma)
m.set_array(i[:])
m.set_clim(overall_min_sfo3max_avg, overall_max_sfo3max_avg)
# Additional necessary information
cbar = plt.colorbar(m, boundaries=np.arange(overall_min_sfo3max_avg, overall_max_sfo3max_avg
+ 0.5e-08, 0.5e-08))
cbar.set_label('mol mol-1')
# plot here only the 1st item in your sfo3max_avg list.
cs = ax.contourf(lon[:], lat[:], sfo3max_avg[0][:], cmap='magma')
# Adding axis labels - latitude & longitude
gridl = ax.gridlines(color="black", linestyle="dotted", draw_labels=True)
gridl.xformatter=LONGITUDE_FORMATTER
gridl.yformatter=LATITUDE_FORMATTER
gridl.xlabels_top = False
gridl.ylabels_right = False
plt.ion() # set interactive mode
plt.show()
# finally plot the 17 global plots of sfo3max_avg
for k in sfo3max_avg:
cs = ax.contourf(lon[:], lat[:], k[:], cmap='magma')
plt.gcf().canvas.draw()
plt.pause(1) #control the interval between successive displays, currently set to 1 sec.

Related

Plot dual points with one point fixed

I'm trying to plot a set of points with a special feature,
first plot 2 points with a random coordinates x and y, in a range from 0 to 200,
but my problem is how can set this points as fixed or centers, take this center-points and from this points, plot one new point with random coordinates(as pairs of points A-a, B-b, etc), and define the distance that can't be higher than 30 meter or units of distance beetwen this points. To get the points like this
I add part of my code to make this
import matplotlib as mpl
from matplotlib.figure import Figure
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from itertools import product
from matplotlib.lines import Line2D
fig,ax=plt.subplots()
#AP POINTS
###################################################
points_xA=np.random.randint(0,200)
points_yA=np.random.randint(0,200)
points_xB=np.random.randint(0,200)
points_yB=np.random.randint(0,200)
center1=np.array([points_xA,points_yB])
center2=np.array([points_xB,points_yB])
ax.annotate("A",xy=(center1),fontsize=12,bbox={"boxstyle":"circle","color":"orange"})
ax.annotate("B",xy=(center2),fontsize=12,bbox={"boxstyle":"circle","color":"orange"})
#STA POINTS
######################################################
#points_xa=np.random.randint()
#points_ya=np.random.randint()
#points_xb=np.random.randint()
#points_yb=np.random.randint()
######################################################
#LABELS
plt.title('random points')
plt.xlabel('x(m)')
plt.ylabel('y(m)')
plt.xlim(0,210)
plt.ylim(0,210)
plt.grid(True)
plt.show()
i have develop a script that plot points as i wanted, but it have some issues:
1.- The menu or bar where the zoom functions, save image, etc. It disappeared and I can't zoom, which I think would be the most important thing.
2.- The table where is the coordinates of each point, for example, for AP_A it have his STA_A1 o more, depending how many STA's you want( for 3 STA's it would be STA_A1, STA_A2, STA_A3, etc)
but in the table apears as STA_A1, for any STA, in the next image it's more clear
I hope it will be useful to someone, on the other hand if someone can correct those errors in my code it would be great, I thank to this community where I have found some solutions on several occasions.
code:
import matplotlib as mpl
from matplotlib.figure import Figure
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches
from itertools import product
from matplotlib.lines import Line2D
##########################
#RADIOS
radius1=30
#radius2=30
#AP POINTS
###################################################
def setNodos(n,rango=300,n_clientes=6):
listaNodos = []
for i in range(n):
points_x=np.random.randint(0,rango)
points_y=np.random.randint(0,rango)
listaNodos.append((np.array([points_x,points_y]),n_clientes))
return listaNodos
listaNodos = setNodos(4,300,3)
abc = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
points_x = []
points_y = []
sta_cant = []
points_sta_x = []
points_sta_y = []
sta_names = []
for nodo,n in listaNodos:
points_x.append(nodo[0])
points_y.append(nodo[1])
sta_cant.append(n)
t_data=[]
########################################
fig = plt.figure(figsize = (15,10))
ax = plt.subplot2grid((3,2), (0, 0),colspan=2,rowspan=2)
l=0
sta_n=0
print(listaNodos)
for centerA,sta_n in listaNodos:
cxA,cyA = centerA
ax.annotate(abc[l],xy=(centerA),fontsize=12,bbox={"boxstyle":"circle","color":"orange"})
#RADIO CIRCULO ROJO
ct1A=np.linspace(0,2*np.pi)
circx11,circy12 = radius1*np.cos(ct1A)+cxA, radius1*np.sin(ct1A)+cyA
plt.plot(circx11, circy12, ls="-",color='red')
#RELLENO CIRCULO ROJO
ax= plt.gca()
t1= plt.Polygon([[i,j] for i, j in zip(circx11,circy12)], color='slategrey', alpha=0.2)
ax.add_patch(t1)
######################################################
#STA POINTS
######################################################
r_sta = np.random.randint(0,radius1,size=sta_n)
tita_sta = np.random.randint(0,359,size=sta_n)
x_sta = np.round(r_sta*np.cos(tita_sta)+cxA,0)
y_sta = np.round(r_sta*np.sin(tita_sta)+cyA,0)
print(x_sta,y_sta)
for x,y in zip(x_sta,y_sta):
#plt.scatter(x,y,c='b',zorder=1000)
x = np.min((300,np.max((0,int(x)))))
y = np.min((300,np.max((0,int(y)))))
ax.annotate(abc[l].lower(),xy=((x,y)),fontsize=10,color='black',
bbox={"boxstyle":"circle","color":"steelblue","alpha":0.5},
)
sta_names.append('STA_%s%i'%(abc[l],l+1))
points_sta_x.append(x)
points_sta_y.append(y)
l+=1
######################################################
#Tabla con coordenadas
plt.xlabel('x(m)')
plt.ylabel('y(m)')
plt.xlim(-10,310)
plt.ylim(-10,310)
ax.grid(True)
plt.title('random points')
t_data.append(points_x+points_sta_x)
t_data.append(points_y+points_sta_y)
print(t_data)
print(sta_n)
collLabels =[('AP_%s'%i) for i in abc[:len(points_x)]]
for name in sta_names:
collLabels.append(name)
print(collLabels)
ax1 = plt.subplot2grid((3,2), (2, 0),colspan=2,rowspan=1)
table=ax1.table(cellText = t_data,
colLabels=collLabels,
rowLabels=('coord_x','coord_y'),
bbox=[0,0.3,0.1+0.05*len(collLabels),0.6+0.01*len(collLabels)]
,cellLoc='center',fontsize=30)
plt.xticks([])
plt.yticks([])
plt.axis('OFF')
plt.tight_layout(rect=[0.01, 0.01, 1.0, 1.0])
#######################################################
#LABELS
ax.set_aspect('equal')
plt.savefig('./salida/escen_random.png')
plt.show()

Why can't I use cartopy to plot certain time averages of the same dataset?

I have a 3-dimensional xarray DataArray of changes in surface temperature with coordinates of time, lat and lon. I am visualizing the data using Cartopy. You can find the 125 MB file here.
While producing plots of time-averages over different periods, I've found that I'm unable to produce orthographic projections when including certain time steps, such as the 132nd (index 131) time. Here is a plot of the time average from 0 to 130:
But this happens when I instead perform the time average from 0 to 131:
Here is the code I used to produce the plots:
# import statements
import cartopy.crs as ccrs
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
from cartopy.util import add_cyclic_point
%matplotlib inline
%config InlineBackend.figure_format = "jpg"
# read in data
ens_mean = xr.open_dataarray('temp_changes_ens_mean.nc')
# time average subset of data
to_plot = ens_mean.isel(time=slice(None,131)).mean(dim='time') # change 130 to 131 to break cartopy
# add cyclic point to avoid white lines
data = to_plot
lon = to_plot.coords['lon']
lon_idx = data.dims.index('lon')
wrap_data, wrap_lon = add_cyclic_point(data.values, coord=lon, axis=lon_idx)
# make an orthographic plot centered on north pole
fig = plt.figure(figsize=(4.5,3.5))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(0, 90))
ax.coastlines()
im = ax.contourf(wrap_lon, to_plot.lat, wrap_data,
transform=ccrs.PlateCarree())
# add colorbar
cb = fig.colorbar(im,orientation='horizontal',shrink=0.5,pad=0.05)
cb.ax.tick_params(labelsize=8)
cb.set_label('ΔSAT (K)',fontsize=8)
plt.tight_layout(w_pad=0.05)
plt.show()
This occurs whether I add a cyclic point or not. I am able to make quick plots of the data using matplotlib or xarray's built-in plotting without error. I've already checked for NaN values in the data. Lastly, if I remove the transform argument in the contourf line, it is able to produce a coherent plot, which leads me to think it is the transformation step that produces this odd plot.
Thanks for the help!
You can use ax.set_global() method to reset the coordinate limits:
#!/usr/bin/env ipython
# --------------------------------------------
import cartopy.crs as ccrs
import xarray as xr
import numpy as np
import matplotlib.pyplot as plt
from cartopy.util import add_cyclic_point
# --------------------------------------------------------------------------------------
#%matplotlib inline
#%config InlineBackend.figure_format = "jpg"
# read in data
ens_mean = xr.open_dataarray('temp_changes_ens_mean.nc')
# time average subset of data
to_plot = ens_mean.isel(time=slice(None,131)).mean(dim='time') # change 130 to 131 to break cartopy
# add cyclic point to avoid white lines
data = to_plot
lon = to_plot.coords['lon']
lon_idx = data.dims.index('lon')
wrap_data, wrap_lon = add_cyclic_point(data.values, coord=lon, axis=lon_idx)
# ------------------------------------------------------------------
# this is not working:
xlims = (np.min(ens_mean['lon']),np.max(ens_mean['lon']));
ylims = (np.min(ens_mean['lat']),np.max(ens_mean['lat']));
# ------------------------------------------------------------------
lon = to_plot.coords['lon']
# ====================================================================================
# make an orthographic plot centered on north pole
# Let us make a working/satisfying plot:
fig = plt.figure(figsize=(4.5,3.5))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.Orthographic(0, 90))
ax.coastlines()
im = ax.contourf(wrap_lon, to_plot.lat, wrap_data,
transform=ccrs.PlateCarree())
# -----------------------------------------------------------
# add colorbar
cb = fig.colorbar(im,orientation='horizontal',shrink=0.5,pad=0.05)
cb.ax.tick_params(labelsize=8)
cb.set_label('ΔSAT (K)',fontsize=8)
plt.tight_layout(w_pad=0.05)
ax.set_global();
#ax.set_xlim(xlims);
#ax.set_ylim(ylims);
plt.show()

Coloring points based on a variable value

I have a dataset of temperature values at a network of weather stations. I am looking to plot the data on a map, with the points colored based on the temperature at that station. Is there such capability found in Python/Matplotlib to do this?
For reference: My dataset is in a netCDF file and contains lat/lon values of each station. The temperature variable is a function of station and time. So far, I have plotted the points on a map using Cartopy, but with one color for each point.
You're looking for the scatter plotting command, using the c argument:
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import matplotlib.pyplot as plt
import numpy as np
lon = np.random.rand(50) * 50 - 120
lat = np.random.rand(50) * 25 + 25
temps = np.random.randn(50) * 10 + 25
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection=ccrs.LambertConformal())
ax.scatter(lon, lat, c=temps, transform=ccrs.PlateCarree())
ax.add_feature(cfeature.COASTLINE)
ax.add_feature(cfeature.BORDERS)

matplotlib overlay a normal distribution with stddev axis onto another plot

I have a series of data that I'm reading in from a tutorial site.
I've managed to plot the distribution of the TV column in that data, however I also want to overlay a normal distribution curve with StdDev ticks on a second x-axis (so I can compare the two curves). I'm struggling to work out how to do it..
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
import matplotlib.mlab as mlab
import math
# read data into a DataFrame
data = pd.read_csv('http://www-bcf.usc.edu/~gareth/ISL/Advertising.csv', index_col=0)
# draw distribution curve
h = sorted(data.TV)
hmean = np.mean(h)
hstd = np.std(h)
pdf = stats.norm.pdf(h, hmean, hstd)
plt.plot(h, pdf)
Here is a diagram close to what I'm after, where x is the StdDeviations. All this example needs is a second x axis to show the values of data.TV
Not sure what you really want, but you could probably use second axis like this
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
import matplotlib.mlab as mlab
import math
# read data into a DataFrame
data = pd.read_csv('Advertising.csv', index_col=0)
fig, ax1 = plt.subplots()
# draw distribution curve
h = sorted(data.TV)
ax1.plot(h,'b-')
ax1.set_xlabel('TV')
ax1.set_ylabel('Count', color='b')
for tl in ax1.get_yticklabels():
tl.set_color('b')
hmean = np.mean(h)
hstd = np.std(h)
pdf = stats.norm.pdf(h, hmean, hstd)
ax2 = ax1.twinx()
ax2.plot(h, pdf, 'r.')
ax2.set_ylabel('pdf', color='r')
for tl in ax2.get_yticklabels():
tl.set_color('r')
plt.show()
Ok, assuming that you want to plot the distribution of your data, the fitted normal distribution with two x-axes, one way to achieve this is as follows.
Plot the normalized data together with the standard normal distribution. Then use matplotlib's twiny() to add a second x-axis to the plot. Use the same tick positions as the original x-axis on the second axis, but scale the labels so that you get the corresponding original TV values. The result looks like this:
Code
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
import matplotlib.mlab as mlab
import math
# read data into a DataFrame
data = pd.read_csv('http://www-bcf.usc.edu/~gareth/ISL/Advertising.csv', index_col=0)
h = sorted(data.TV)
hmean = np.mean(h)
hstd = np.std(h)
h_n = (h - hmean) / hstd
pdf = stats.norm.pdf( h_n )
# plot data
f,ax1 = plt.subplots()
ax1.hist( h_n, 20, normed=1 )
ax1.plot( h_n , pdf, lw=3, c='r')
ax1.set_xlim( [h_n.min(), h_n.max()] )
ax1.set_xlabel( r'TV $[\sigma]$' )
ax1.set_ylabel( r'Relative Frequency')
ax2 = ax1.twiny()
ax2.grid( False )
ax2.set_xlim( ax1.get_xlim() )
ax2.set_ylim( ax1.get_ylim() )
ax2.set_xlabel( r'TV' )
ticklocs = ax2.xaxis.get_ticklocs()
ticklocs = [ round( t*hstd + hmean, 2) for t in ticklocs ]
ax2.xaxis.set_ticklabels( map( str, ticklocs ) )

shapefile and matplotlib: plot polygon collection of shapefile coordinates

I'm trying to plot filled polygons of countries on the world map with matplotlib in python.
I've got a shapefile with country boundary coordinates of every country. Now, I want to convert these coordinates (for each country) into a polygon with matplotlib. Without using Basemap. Unfortunately, the parts are crossing or overlapping. Is there a workarund, maybe using the distance from point to point.. or reordering them ?
Ha!
I found out, how.. I completely neglected, the sf.shapes[i].parts information! Then it comes down to:
# -- import --
import shapefile
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
# -- input --
sf = shapefile.Reader("./shapefiles/world_countries_boundary_file_world_2002")
recs = sf.records()
shapes = sf.shapes()
Nshp = len(shapes)
cns = []
for nshp in xrange(Nshp):
cns.append(recs[nshp][1])
cns = array(cns)
cm = get_cmap('Dark2')
cccol = cm(1.*arange(Nshp)/Nshp)
# -- plot --
fig = plt.figure()
ax = fig.add_subplot(111)
for nshp in xrange(Nshp):
ptchs = []
pts = array(shapes[nshp].points)
prt = shapes[nshp].parts
par = list(prt) + [pts.shape[0]]
for pij in xrange(len(prt)):
ptchs.append(Polygon(pts[par[pij]:par[pij+1]]))
ax.add_collection(PatchCollection(ptchs,facecolor=cccol[nshp,:],edgecolor='k', linewidths=.1))
ax.set_xlim(-180,+180)
ax.set_ylim(-90,90)
fig.savefig('test.png')
Then it will look like this:
Here is another piece of code I used to plot polygon shapefiles. It uses GDAL/OGR to read shapefile and plots correctly donut shape polygons:
from osgeo import ogr
import numpy as np
import matplotlib.path as mpath
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt
# Extract first layer of features from shapefile using OGR
ds = ogr.Open('world_countries_boundary_file_world_2002.shp')
nlay = ds.GetLayerCount()
lyr = ds.GetLayer(0)
# Get extent and calculate buffer size
ext = lyr.GetExtent()
xoff = (ext[1]-ext[0])/50
yoff = (ext[3]-ext[2])/50
# Prepare figure
fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim(ext[0]-xoff,ext[1]+xoff)
ax.set_ylim(ext[2]-yoff,ext[3]+yoff)
paths = []
lyr.ResetReading()
# Read all features in layer and store as paths
for feat in lyr:
geom = feat.geometry()
codes = []
all_x = []
all_y = []
for i in range(geom.GetGeometryCount()):
# Read ring geometry and create path
r = geom.GetGeometryRef(i)
x = [r.GetX(j) for j in range(r.GetPointCount())]
y = [r.GetY(j) for j in range(r.GetPointCount())]
# skip boundary between individual rings
codes += [mpath.Path.MOVETO] + \
(len(x)-1)*[mpath.Path.LINETO]
all_x += x
all_y += y
path = mpath.Path(np.column_stack((all_x,all_y)), codes)
paths.append(path)
# Add paths as patches to axes
for path in paths:
patch = mpatches.PathPatch(path, \
facecolor='blue', edgecolor='black')
ax.add_patch(patch)
ax.set_aspect(1.0)
plt.show()
from fiona import collection
import matplotlib.pyplot as plt
from descartes import PolygonPatch
from matplotlib.collections import PatchCollection
from itertools import imap
from matplotlib.cm import get_cmap
cm = get_cmap('Dark2')
figure, axes = plt.subplots(1)
source_path = "./shapefiles/world_countries_boundary_file_world_2002"
with collection(source_path, 'r') as source:
patches = imap(PolygonPatch, (record['geometry'] for record in source)
axes.add_collection( PatchCollection ( patches, cmap=cm, linewidths=0.1 ) )
axes.set_xlim(-180,+180)
axes.set_ylim(-90,90)
plt.show()
Note this assumes polygons, MultiPolygons can be handles in a similar manner with
map(PolygonPatch, MultiPolygon(record['geometry']))
Regarding to #hannesk's answer, you should add the following imports: from numpy import array and import matplotlib and replace the line cm = get_cmap('Dark2') by cm = matplotlib.cm.get_cmap('Dark2')
(I'm not so famous to add a comment to the noticed post.)

Categories

Resources