Q: I want to draw a box on my cartopy map defined by the longitude max/min and the latitude max/min.
Imports:
import cartopy
import cartopy.feature as cpf
from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter
from shapely import geometry
from collections import namedtuple
from shapely.geometry.polygon import LinearRing
I have my Region objects defining the bounds of the boxes.
Region = namedtuple('Region',field_names=['region_name','lonmin','lonmax','latmin','latmax'])
region = Region(
region_name="all_region",
lonmin = 32.6,
lonmax = 51.8,
latmin = -5.0,
latmax = 15.2,
)
sub_region = Region(
region_name="highlands_region",
lonmin=35,
lonmax=40,
latmin=5.5,
latmax=12.5
)
My functions
The plot_polygon and add_sub_region_box functions don't work, in that neither produces a bounding box. I get an error message with add_sub_region_box but plot_polygon gives nothing back.
def plot_geog_location(region, lakes=False, borders=False, rivers=False):
""" use cartopy to plot the region (defined as a namedtuple object)
Arguments:
---------
: region (Region namedtuple)
region of interest bounding box defined in engineering/regions.py
: lakes (bool)
show lake features
: borders (bool)
show lake features
: rivers (bool)
show river features (#10m scale from NaturalEarth)
"""
lonmin,lonmax,latmin,latmax = region.lonmin,region.lonmax,region.latmin,region.latmax
ax = plt.figure().gca(projection=cartopy.crs.PlateCarree())
ax.add_feature(cpf.COASTLINE)
if borders:
ax.add_feature(cpf.BORDERS, linestyle=':')
if lakes:
ax.add_feature(cpf.LAKES)
if rivers:
# assert False, "Rivers are not yet working in this function"
water_color = '#3690f7'
river_feature = get_river_features()
ax.add_feature(river_feature)
ax.set_extent([lonmin, lonmax, latmin, latmax])
# plot the lat lon labels
# https://scitools.org.uk/cartopy/docs/v0.15/examples/tick_labels.html
# https://stackoverflow.com/questions/49956355/adding-gridlines-using-cartopy
xticks = np.linspace(lonmin, lonmax, 5)
yticks = np.linspace(latmin, latmax, 5)
ax.set_xticks(xticks, crs=cartopy.crs.PlateCarree())
ax.set_yticks(yticks, crs=cartopy.crs.PlateCarree())
lon_formatter = LongitudeFormatter(zero_direction_label=True)
lat_formatter = LatitudeFormatter()
ax.xaxis.set_major_formatter(lon_formatter)
ax.yaxis.set_major_formatter(lat_formatter)
fig = plt.gcf()
return fig, ax
def plot_polygon(ax, sub_region):
"""
https://groups.google.com/forum/#!topic/scitools-iris/LxR0EbQolyE
Note:
----
order is important:
lower-left, upper-left, upper-right, lower-right
2 -- 3
| |
1 -- 4
"""
# ax = fig.axes[0]
lons = [sub_region.latmin, sub_region.latmin, sub_region.latmax, sub_region.latmax]
lats = [sub_region.lonmin, sub_region.lonmax, sub_region.lonmax, sub_region.lonmin]
ring = LinearRing(list(zip(lons, lats)))
ax.add_geometries([ring], cartopy.crs.PlateCarree(), facecolor='b', edgecolor='black', alpha=0.5)
return ax
def add_sub_region_box(ax, subregion):
""" """
geom = geometry.box(minx=subregion.lonmin,maxx=subregion.lonmax,miny=subregion.latmin,maxy=subregion.latmax)
ax.add_geometries(geom, crs=cartopy.crs.PlateCarree(), alpha=0.3)
return ax
Neither of the functions work! Any help would be very much appreciated.
Running the functions:
fig, ax = plot_geog_location(region,borders=True, lakes=True, rivers=False)
plot_polygon(ax, sub_region)
fig, ax = plot_geog_location(region,borders=True, lakes=True, rivers=False)
add_sub_region_box(ax, sub_region)
In def add_sub_region_box(), the method .add_geometries() requires iterable objects. So that, instead of geom you need [geom] to get it right.
ax.add_geometries([geom], crs=cartopy.crs.PlateCarree(), alpha=0.3)
Here is the resulting plot:
Related
I have created a Basemap of Asia using following lines of code. The projection used is "marcator". The region I want to show in this basemap is Chitwan, Nepal. The coordinates is also provided.
from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
chitwan = (27.618556599999998, 84.45385600798173)
fig = plt.figure()
ax = fig.add_axes([0.5, 0.5, 2, 2]) #left, bottom, width, height
m = Basemap(
llcrnrlon = 30,
llcrnrlat = 0,
urcrnrlon = 120,
urcrnrlat = 60,
projection = "merc",
resolution = "l"
)
m.plot(chitwan[1], chitwan[0],
latlon = True,
marker = "s",
color = "blue",
markersize = 20)
m.drawcoastlines()
m.fillcontinents()
m.drawcountries()
m.drawstates()
plt.annotate(text = "Chitwan, Nepal", xy = chitwan)
plt.show()
I am able to add a blue square marker in Chitwan, Nepal using
m.plot(chitwan[1], chitwan[0],
latlon = True,
marker = "s",
color = "blue",
markersize = 40)
Passing latlon = True allows me to draw the marker using the coordinates of the place directly.
However, I also want to annotate "Chitwan, Nepal" as a text in the same location.
I tried plt.annotate(text = "Chitwan, Nepal", xy = chitwan). However, this plots the text on the lower left corner of the Basemap as shown below.
I think this should be because the latitude and longitude coordinates of the text is not projected to that of the Basemap. So how can I project the coordinates of my location such that the text is also inserted in the same location as the marker? Is it possible to do this by passing the exact coordinates of the place directly and passing an argument similar to latlon = True for the marker?
Ok. I figured out the way for this myself.
I need to use:
x, y = m(chitwan[1], chitwan[0])
The x and y are projected to the map location with longitude and latitude of chitwan respectively.
And then I annotated the text as follows:
ax.annotate(text = "Chitwan, Nepal",
xy = (x+5,y+5),
)
I get the resulting plot as shown:
I am using a github repository called ptitprince, which is derived from seaborn and matplotlib, to generate graphs.
For example, this is the code using the ptitprince repo:
# coding: utf8
import pandas as pd
import ptitprince as pt
import seaborn as sns
import os
import matplotlib.pyplot as plt
#sns.set(style="darkgrid")
#sns.set(style="whitegrid")
#sns.set_style("white")
sns.set(style="whitegrid",font_scale=2)
import matplotlib.collections as clt
df = pd.read_csv ("u118phag.csv", sep= ",")
df.head()
savefigs = True
figs_dir = 'figs'
if savefigs:
# Make the figures folder if it doesn't yet exist
if not os.path.isdir('figs'):
os.makedirs('figs')
#automation
f, ax = plt.subplots(figsize=(4, 5))
#f.subplots_adjust(hspace=0,wspace=0)
dx = "Treatment"; dy = "score"; ort = "v"; pal = "Set2"; sigma = .2
ax=pt.RainCloud(x = dx, y = dy, data = df, palette = pal, bw = sigma,
width_viol = .6, ax = ax, move=.2, offset=.1, orient = ort, pointplot = True)
f.show()
if savefigs:
f.savefig('figs/figure20.png', bbox_inches='tight', dpi=500)
which generates the following graph
The raw code not using ptitprince is as follows and produces the same graph as above:
# coding: utf8
import pandas as pd
import ptitprince as pt
import seaborn as sns
import os
import matplotlib.pyplot as plt
#sns.set(style="darkgrid")
#sns.set(style="whitegrid")
#sns.set_style("white")
sns.set(style="whitegrid",font_scale=2)
import matplotlib.collections as clt
df = pd.read_csv ("u118phag.csv", sep= ",")
df.head()
savefigs = True
figs_dir = 'figs'
if savefigs:
# Make the figures folder if it doesn't yet exist
if not os.path.isdir('figs'):
os.makedirs('figs')
f, ax = plt.subplots(figsize=(7, 5))
dy="Treatment"; dx="score"; ort="h"; pal = sns.color_palette(n_colors=1)
#adding color
pal = "Set2"
f, ax = plt.subplots(figsize=(7, 5))
ax=pt.half_violinplot( x = dx, y = dy, data = df, palette = pal, bw = .2, cut = 0.,
scale = "area", width = .6, inner = None, orient = ort)
ax=sns.stripplot( x = dx, y = dy, data = df, palette = pal, edgecolor = "white",
size = 3, jitter = 1, zorder = 0, orient = ort)
ax=sns.boxplot( x = dx, y = dy, data = df, color = "black", width = .15, zorder = 10,\
showcaps = True, boxprops = {'facecolor':'none', "zorder":10},\
showfliers=True, whiskerprops = {'linewidth':2, "zorder":10},\
saturation = 1, orient = ort)
if savefigs:
f.savefig('figs/figure21.png', bbox_inches='tight', dpi=500)
Now, what I'm trying to do is to figure out how to modify the graph so that I can (1) move the plots closer together, so there is not so much white space between them, and (2) shift the x-axis to the right, so that I can make the distribution (violin) plot wider without it getting cut in half by the y-axis.
I have tried to play around with subplots_adjust() as you can see in the first box of code, but I receive an error. I cannot figure out how to appropriately use this function, or even if that will actually bring the different graphs closer together.
I also know that I can increase the distribution size by increasing this value width = .6, but if I increase it too high, the distribution plot begins to being cut off by the y-axis. I can't figure out if I need to adjust the overall plot using the plt.subplots,or if I need to move each individual plot.
Any advice or recommendations on how to change the visuals of the graph? I've been staring at this for awhile, and I can't figure out how to make seaborn/matplotlib play nicely with ptitprince.
You may try to change the interval of X-axis being shown using ax.set_xbound (put a lower value than you currently have for the beginning).
I have a 2D array value_1 which depends on lon(longitude) and lat(latitude).
Now, I can use pcolormesh to plot the value on one figure.
But, I have another 3D array value_2 which depends on lon, lat and pressure (levels of pressure).
If I want to show the profile (depends on value_2 and pressure) and coordinate like this: (-120,20) when the mouse hover or click on one grid(lon,lat), how could I make it?
Here's the example of plotting pseudocolor plot and profile plot:
import numpy as np
import matplotlib.pyplot as plt
# coordination
lon = np.arange(-120,-110,1)
lat = np.arange(20,30,1)
# shape of value_1: (lon,lat)
# pseudocolor plot
value_1 = np.random.rand(9,9)
pressure = np.arange(1110,500,-100)
lon,lat = np.meshgrid(lon,lat)
plt.pcolormesh(lon,lat,value_1)
plt.colorbar()
plt.show()
# shape of value_2: (lon,lat,pressure)
# profile plot
# Used to plot profile when mouse hovers on one grid
value_2 = np.random.rand(9,9,pressure.shape[0])
I'm sure there a more efficient way to get the right indices when hovering over the pcolormesh, but this does the trick:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gs
from math import floor
# coordination
lon = np.arange(-120, -110, 1)
lat = np.arange(20, 30, 1)
# shape of value_1: (lon,lat)
# pseudocolor plot
value_1 = np.random.rand(9, 9)
pressure = np.arange(1110, 500, -100)
mlon, mlat = np.meshgrid(lon, lat)
# shape of value_2: (lon,lat,pressure)
# profile plot
# Used to plot profile when mouse hovers on one grid
value_2 = np.random.rand(9, 9, pressure.shape[0])
# global variables to keep track of which values
# are currently plotted in ax2
current_lat, curret_lon = None, None
fig, (ax1, ax2) = plt.subplots(2,1)
m = ax1.pcolormesh(mlon, mlat, value_1)
fig.colorbar(m, ax=ax1)
fig.tight_layout()
def on_move(event):
global current_lat, current_lon
if event.inaxes is ax1:
event_lat = floor(event.ydata)
event_lon = floor(event.xdata)
# find the indices corresponding to lat,lon
id_lat = np.searchsorted(lat, event_lat)
id_lon = np.searchsorted(lon, event_lon)
# only plot if we have different values than the previous plot
if id_lat != current_lat or id_lon != current_lon:
current_lat = id_lat
current_lon = id_lon
ax2.cla()
ax2.plot(value_2[id_lat, id_lon, :], pressure)
ax2.set_title("lat: {:.0f}, lon: {:.0f}".format(event_lat, event_lon))
fig.canvas.draw_idle()
cid = fig.canvas.mpl_connect('motion_notify_event', on_move)
plt.show()
I am trying to create a plot using matplotlib but I get an error, and after hours of searching, I do not see an alternative or something that works. Here's the code that's giving me trouble:
import matplotlib.transforms as transforms
self.transDataToAxes = self.transScale + (self.transLimits +
transforms.Affine2D().skew_deg(rot, 0))
Which gives me the error: AttributeError: 'Affine2D' object has no attribute 'skew_deg'. This error happens with both python 2.7 and python 3.
If anyone has any suggestions on what I can try, it would be greatly appreciated.
Edit: Here is the entire script which I am trying to run, it should also be noted that I've tried this on Windows, Linux, and Mac with no success:
import matplotlib
spc_file = open('1OUN.txt', 'r').read()
import sharppy
import sharppy.sharptab.profile as profile
import sharppy.sharptab.interp as interp
import sharppy.sharptab.winds as winds
import sharppy.sharptab.utils as utils
import sharppy.sharptab.params as params
import sharppy.sharptab.thermo as thermo
import numpy as np
from StringIO import StringIO
def parseSPC(spc_file):
## read in the file
data = np.array([l.strip() for l in spc_file.split('\n')])
## necessary index points
title_idx = np.where( data == '%TITLE%')[0][0]
start_idx = np.where( data == '%RAW%' )[0] + 1
finish_idx = np.where( data == '%END%')[0]
## create the plot title
data_header = data[title_idx + 1].split()
location = data_header[0]
time = data_header[1][:11]
## put it all together for StringIO
full_data = '\n'.join(data[start_idx : finish_idx][:])
sound_data = StringIO( full_data )
## read the data into arrays
p, h, T, Td, wdir, wspd = np.genfromtxt( sound_data, delimiter=',', comments="%", unpack=True )
return p, h, T, Td, wdir, wspd
pres, hght, tmpc, dwpc, wdir, wspd = parseSPC(spc_file)
prof = profile.create_profile(profile='default', pres=pres, hght=hght, tmpc=tmpc, \
dwpc=dwpc, wspd=wspd, wdir=wdir, missing=-9999, strictQC=True)
import matplotlib.pyplot as plt
plt.plot(prof.tmpc, prof.hght, 'r-')
plt.plot(prof.dwpc, prof.hght, 'g-')
#plt.barbs(40*np.ones(len(prof.hght)), prof.hght, prof.u, prof.v)
plt.xlabel("Temperature [C]")
plt.ylabel("Height [m above MSL]")
plt.grid()
plt.show()
msl_hght = prof.hght[prof.sfc] # Grab the surface height value
agl_hght = interp.to_agl(prof, msl_hght) # Converts to AGL
msl_hght = interp.to_msl(prof, agl_hght) # Converts to MSL
plt.plot(thermo.ktoc(prof.thetae), prof.hght, 'r-', label='Theta-E')
plt.plot(prof.wetbulb, prof.hght, 'c-', label='Wetbulb')
plt.xlabel("Temperature [C]")
plt.ylabel("Height [m above MSL]")
plt.legend()
plt.grid()
plt.show()
sfcpcl = params.parcelx( prof, flag=1 ) # Surface Parcel
#fcstpcl = params.parcelx( prof, flag=2 ) # Forecast Parcel
#mupcl = params.parcelx( prof, flag=3 ) # Most-Unstable Parcel
#mlpcl = params.parcelx( prof, flag=4 ) # 100 mb Mean Layer Parcel
# This serves as an intensive exercise of matplotlib's transforms
# and custom projection API. This example produces a so-called
# SkewT-logP diagram, which is a common plot in meteorology for
# displaying vertical profiles of temperature. As far as matplotlib is
# concerned, the complexity comes from having X and Y axes that are
# not orthogonal. This is handled by including a skew component to the
# basic Axes transforms. Additional complexity comes in handling the
# fact that the upper and lower X-axes have different data ranges, which
# necessitates a bunch of custom classes for ticks,spines, and the axis
# to handle this.
from matplotlib.axes import Axes
import matplotlib.transforms as transforms
import matplotlib.axis as maxis
import matplotlib.spines as mspines
import matplotlib.path as mpath
from matplotlib.projections import register_projection
# The sole purpose of this class is to look at the upper, lower, or total
# interval as appropriate and see what parts of the tick to draw, if any.
class SkewXTick(maxis.XTick):
def draw(self, renderer):
if not self.get_visible(): return
renderer.open_group(self.__name__)
lower_interval = self.axes.xaxis.lower_interval
upper_interval = self.axes.xaxis.upper_interval
if self.gridOn and transforms.interval_contains(
self.axes.xaxis.get_view_interval(), self.get_loc()):
self.gridline.draw(renderer)
if transforms.interval_contains(lower_interval, self.get_loc()):
if self.tick1On:
self.tick1line.draw(renderer)
if self.label1On:
self.label1.draw(renderer)
if transforms.interval_contains(upper_interval, self.get_loc()):
if self.tick2On:
self.tick2line.draw(renderer)
if self.label2On:
self.label2.draw(renderer)
renderer.close_group(self.__name__)
# This class exists to provide two separate sets of intervals to the tick,
# as well as create instances of the custom tick
class SkewXAxis(maxis.XAxis):
def __init__(self, *args, **kwargs):
maxis.XAxis.__init__(self, *args, **kwargs)
self.upper_interval = 0.0, 1.0
def _get_tick(self, major):
return SkewXTick(self.axes, 0, '', major=major)
#property
def lower_interval(self):
return self.axes.viewLim.intervalx
def get_view_interval(self):
return self.upper_interval[0], self.axes.viewLim.intervalx[1]
# This class exists to calculate the separate data range of the
# upper X-axis and draw the spine there. It also provides this range
# to the X-axis artist for ticking and gridlines
class SkewSpine(mspines.Spine):
def _adjust_location(self):
trans = self.axes.transDataToAxes.inverted()
if self.spine_type == 'top':
yloc = 1.0
else:
yloc = 0.0
left = trans.transform_point((0.0, yloc))[0]
right = trans.transform_point((1.0, yloc))[0]
pts = self._path.vertices
pts[0, 0] = left
pts[1, 0] = right
self.axis.upper_interval = (left, right)
# This class handles registration of the skew-xaxes as a projection as well
# as setting up the appropriate transformations. It also overrides standard
# spines and axes instances as appropriate.
class SkewXAxes(Axes):
# The projection must specify a name. This will be used be the
# user to select the projection, i.e. ``subplot(111,
# projection='skewx')``.
name = 'skewx'
def _init_axis(self):
#Taken from Axes and modified to use our modified X-axis
self.xaxis = SkewXAxis(self)
self.spines['top'].register_axis(self.xaxis)
self.spines['bottom'].register_axis(self.xaxis)
self.yaxis = maxis.YAxis(self)
self.spines['left'].register_axis(self.yaxis)
self.spines['right'].register_axis(self.yaxis)
def _gen_axes_spines(self):
spines = {'top':SkewSpine.linear_spine(self, 'top'),
'bottom':mspines.Spine.linear_spine(self, 'bottom'),
'left':mspines.Spine.linear_spine(self, 'left'),
'right':mspines.Spine.linear_spine(self, 'right')}
return spines
def _set_lim_and_transforms(self):
"""
This is called once when the plot is created to set up all the
transforms for the data, text and grids.
"""
rot = 30
#Get the standard transform setup from the Axes base class
Axes._set_lim_and_transforms(self)
# Need to put the skew in the middle, after the scale and limits,
# but before the transAxes. This way, the skew is done in Axes
# coordinates thus performing the transform around the proper origin
# We keep the pre-transAxes transform around for other users, like the
# spines for finding bounds
self.transDataToAxes = self.transScale + (self.transLimits +
transforms.Affine2D().skew_deg(rot, 0))
# Create the full transform from Data to Pixels
self.transData = self.transDataToAxes + self.transAxes
# Blended transforms like this need to have the skewing applied using
# both axes, in axes coords like before.
self._xaxis_transform = (transforms.blended_transform_factory(
self.transScale + self.transLimits,
transforms.IdentityTransform()) +
transforms.Affine2D().skew_deg(rot, 0)) + self.transAxes
# Now register the projection with matplotlib so the user can select
# it.
register_projection(SkewXAxes)
pcl = sfcpcl
# Create a new figure. The dimensions here give a good aspect ratio
fig = plt.figure(figsize=(6.5875, 6.2125))
ax = fig.add_subplot(111, projection='skewx')
ax.grid(True)
pmax = 1000
pmin = 10
dp = -10
presvals = np.arange(int(pmax), int(pmin)+dp, dp)
# plot the moist-adiabats
for t in np.arange(-10,45,5):
tw = []
for p in presvals:
tw.append(thermo.wetlift(1000., t, p))
ax.semilogy(tw, presvals, 'k-', alpha=.2)
def thetas(theta, presvals):
return ((theta + thermo.ZEROCNK) / (np.power((1000. / presvals),thermo.ROCP))) - thermo.ZEROCNK
# plot the dry adiabats
for t in np.arange(-50,110,10):
ax.semilogy(thetas(t, presvals), presvals, 'r-', alpha=.2)
plt.title(' OAX 140616/1900 (Observed)', fontsize=14, loc='left')
# Plot the data using normal plotting functions, in this case using
# log scaling in Y, as dicatated by the typical meteorological plot
ax.semilogy(prof.tmpc, prof.pres, 'r', lw=2)
ax.semilogy(prof.dwpc, prof.pres, 'g', lw=2)
ax.semilogy(pcl.ttrace, pcl.ptrace, 'k-.', lw=2)
# An example of a slanted line at constant X
l = ax.axvline(0, color='b', linestyle='--')
l = ax.axvline(-20, color='b', linestyle='--')
# Disables the log-formatting that comes with semilogy
ax.yaxis.set_major_formatter(plt.ScalarFormatter())
ax.set_yticks(np.linspace(100,1000,10))
ax.set_ylim(1050,100)
ax.xaxis.set_major_locator(plt.MultipleLocator(10))
ax.set_xlim(-50,50)
plt.show()
And the text file can be found here, before renaming it: OUN_Sounding
I would like to produce a plot of New Zealand with each region colour coded according to some data. However, the shapefiles I have used to produce the image extend beyond the edge of the land and into the ocean. This means that when I colour the polygons they end up colouring portions of the ocean as well. Not the desired response!
The code I am using is:
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
plt.figure(figsize=(15,15))
lonmax = 180
lonmin = 165
latmax = -33
latmin = -48
map = Basemap(llcrnrlon=lonmin,llcrnrlat=latmin,urcrnrlon=lonmax,urcrnrlat=latmax, resolution = 'i')
map.drawmapboundary(fill_color='white')
map.fillcontinents(color='white',lake_color='white')
map.drawcoastlines()
map.readshapefile('../data/raw/statsnzregional-council-2016-generalised-version-SHP/regional-council-2016-generalised-version', 'regional_council')
ax = plt.gca() # get current axes instance
cm = matplotlib.cm.get_cmap('viridis')
norm = matplotlib.colors.Normalize(vmin=0.05, vmax=0.35)
for info, shape in zip(map.regional_council_info, map.regional_council):
poly = Polygon(shape, facecolor=cm(norm(region_percent[info['REGC2016_N']])),edgecolor='k')
ax.add_patch(poly)
plt.show()
Which produces the below image. This image is very close to what I want but I would like the colouring to stop at the land boundary rather than colouring the ocean as well.
I have looked into Basemap's maskoceans() and believe this is probably the best way to solve this but I don't understand how to apply it to my particular situation (eg, how to access the lat,lons? What is the data array in this case?)
Alternatively is there a way to make the map boundary of New Zealand a hard boundary so only the interior overlap with the polygon patches is printed?
You need some polygons to mask out the excess areas.
Get the mask files (nz_mask_w.shp, nz_mask_e.shp) here:
https://github.com/swatchai/cartopy_asean_proj/tree/master/shape_files
And this is the code:
import matplotlib
import matplotlib.pyplot as plt
from mpl_toolkits.basemap import Basemap
from matplotlib.patches import Polygon
from matplotlib.collections import PatchCollection
import shapefile # used to read my shapefiles
fig = plt.figure(figsize=(15,15))
lonmax = 179.95
lonmin = 165
latmax = -33
latmin = -48
map = Basemap(llcrnrlon=lonmin, \
llcrnrlat=latmin, \
urcrnrlon=lonmax, \
urcrnrlat=latmax, \
resolution = 'i')
# this is map theme (change to your need)
map.readshapefile('data/statsnzregional/regional-council-2016-generalised-version', \
name='regional_council')
ax = plt.gca() # get current axes instance
#cm = matplotlib.cm.get_cmap('viridis')
#norm = matplotlib.colors.Normalize(vmin=0.05, vmax=0.35)
for info, shape in zip(map.regional_council_info, map.regional_council):
poly = Polygon(shape, \
facecolor=cm(norm(int(info['REGC2016']))/100.), \
edgecolor='k', \
zorder=1)
# original:- facecolor=cm(norm(info['REGC2016']))
ax.add_patch(poly)
# mask out the excess areas (use files in data sub folder)
sf = shapefile.Reader("data/nz_mask_w")
ss = sf.shapes()
poly1 = Polygon(ss[0].points)
sf = shapefile.Reader("data/nz_mask_e")
ss = sf.shapes()
poly2 = Polygon(ss[0].points)
ax.add_collection( PatchCollection([poly1,poly2], \
zorder=12, \
facecolor='lightblue', \
edgecolor='lightblue' ) )
map.drawcoastlines(color='blue', linewidth=0.3)
plt.show()