Unexpected behavior from Cartopy - matplotlib

I'm trying to draw a 'straight' line on the surface of the Earth (a great circle), which should appear curved on an orthographic projection that isn't looking straight down on the curve. However, when I try to connect two points with a geodetic line in cartopy I get a line with a kink in it. Where is this kink coming from? And how can I get a correctly rendered great circle segment?
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
lats = [0, 36]
lons = [15, 76]
ax = plt.axes(projection = ccrs.Orthographic(central_longitude=0, central_latitude=45))
ax.plot(lons, lats, transform=ccrs.Geodetic())
ax.set_global()
ax.gridlines()

From the option transform=ccrs.Geodetic(), the implication is that you need great-circle arc as a result of your ax.plot() statement.
Without proper setting of projection._threshold you will get the kinked line as you experienced.
Here is the modified code and the expected result.
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
lats = [0, 36]
lons = [15, 76]
myProj = ccrs.Orthographic(central_longitude=0, central_latitude=45)
myProj._threshold = myProj._threshold/20.
ax = plt.axes(projection = myProj)
ax.plot(lons, lats, transform=ccrs.Geodetic())
ax.set_global()
ax.gridlines()
Smaller values of the threshold will cause the plotted lines to have denser vertices along the lines. Additional vertices are not obtained by simple interpolation when great-circle arcs are required in this case.

Related

Cartopy non-zero central longitude distorted with contourf

I am trying to plot the surface temperature from a NetCDF file using Cartopy and contourf. The domain of my plot is 30S to 60N and 90.044495E to 89.95552E (so all the way around the Earth centered on 90W). Here is a section of my code:
import numpy as np
import wrf as wrf
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
cart_proj = wrf.get_cartopy(skintemp)
lats, lons = wrf.latlon_coords(skintemp)
ax = plt.axes(projection=cart_proj)
ax.coastlines('50m', linewidth=0.8)
clevels = np.linspace(230,300,8)
cmap = plt.cm.YlOrRd
contours_fill = plt.contourf(wrf.to_np(lons), wrf.to_np(lats), skintemp, cmap=cmap, levels = clevels, transform=ccrs.PlateCarree(),extend="both")
cbar = plt.colorbar(contours_fill, shrink = .65, orientation='horizontal', pad=.05)
plt.show()
skintemp, lats and lons are all 2D arrays with dimensions (454, 1483), ordered (lat,lon), and cart_proj = wrf.projection.MercatorWithLatTS.
When I show the plot, it's distorted and incorrect:
I have determined that the issue has to do with the non-zero central longitude. The problem appears to be when the longitude changes from 179.90082 to -179.85632. lons.values[0,370]=179.90082, so I changed contourf to the following:
contours_fill = plt.contourf(wrf.to_np(lons[:,0:371]), wrf.to_np(lats[:,0:371]), skintemp[:,0:371], cmap=cmap, levels = clevels, transform=ccrs.PlateCarree(),extend="both")
which produces the following correct figure:
And when I change contourf to:
contours_fill = plt.contourf(wrf.to_np(lons[:,371:-1]), wrf.to_np(lats[:,371:-1]), skintemp[:,371:-1], cmap=cmap, levels = clevels, transform=ccrs.PlateCarree(),extend="both")
I get the other part of the map:
I cannot seem to get both parts of the map to display correctly together. I tried using contourf twice in the same plot, one for each section of the map, but only the last contourf line plots. Any help would be much appreciated!

Problem with ortho projection and pcolormesh in matplotlib-basemap

I have trouble with the ortho projection and pcolormesh.
It should plot a mesh of grid points. Instead, in the upper right portion of the sphere it plots strange lines instead of grid points. The mapping of the mesh looks off.
I tried the code below.
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
plt.clf()
dpp =1 # degrees per pixel
lons = np.arange(-180,180+dpp,dpp)
lats = -1*np.arange(-90,90+dpp,dpp)
m = Basemap(projection='ortho', lon_0=0, lat_0=-60, resolution='l')
data = np.random.random((np.size(lats), np.size(lons)))
lons, lats = np.meshgrid(lons, lats)
x, y = m(lons, lats)
im = m.pcolormesh(x, y, data, latlon=False, cmap='RdBu')
#im = m.pcolormesh(lons, lats, data, latlon=True, cmap='RdBu')
m.colorbar(im)
plt.show()
I obtain the following plot:
The random noise should be mapped onto the entire sphere, but there is clearly an error in the upper right of the ortho map.
Does anyone else get this error with the included code?
Since basemap would require you to manually filter out unwanted data (those that are "behind the globe"), here is how to do the same with cartopy.
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
proj = ccrs.Orthographic(central_longitude=0.0, central_latitude=-60.0)
plt.figure(figsize=(3, 3))
ax = plt.axes(projection=proj)
dpp =1
lons = np.arange(-180,180+dpp,dpp)
lats = 1*np.arange(-90,90+dpp,dpp)
data = np.random.random((np.size(lats), np.size(lons)))
lons, lats = np.meshgrid(lons, lats)
im = ax.pcolormesh(lons, lats, data, cmap='RdBu', transform=ccrs.PlateCarree())
ax.coastlines(resolution='110m')
ax.gridlines()
plt.show()
A fix to Basemap was suggested in the github basemap thread here

Animate a point moving along path between two points

I want to animate a point moving along a path from one location to another on the map.
For example, I drawn a path from New York to New Delhi, using Geodetic transform. Eg. taken from docs Adding data to the map
plt.plot([ny_lon, delhi_lon], [ny_lat, delhi_lat],
color='blue', linewidth=2, marker='o',
transform=ccrs.Geodetic(),
)
Now i want to move a point along this path.
My idea was to somehow get some (say 50) points, along the path and plot a marker on each point for each frame. But I am not able to find a way to get the points on the path.
I found a function transform_points under classCRS, but I am unable to use this, as this gives me the same number of points i have, not the points in between.
Thanks in advance!
There are a couple of approaches to this.
The matplotlib approach
I'll start with perhaps the most basic if you are familiar with matplotlib, but this approach suffers from indirectly using cartopy's functionality, and is therefore harder to configure/extend.
There is a private _get_transformed_path method on a Line2D object (the thing that is returned from plt.plot). The resulting TransformedPath object has a get_transformed_path_and_affine method, which basically will give us the projected line (in the coordinate system of the Axes being drawn).
In [1]: import cartopy.crs as ccrs
In [3]: import matplotlib.pyplot as plt
In [4]: ax = plt.axes(projection=ccrs.Robinson())
In [6]: ny_lon, ny_lat = -75, 43
In [7]: delhi_lon, delhi_lat = 77.23, 28.61
In [8]: [line] = plt.plot([ny_lon, delhi_lon], [ny_lat, delhi_lat],
...: color='blue', linewidth=2, marker='o',
...: transform=ccrs.Geodetic(),
...: )
In [9]: t_path = line._get_transformed_path()
In [10]: path_in_data_coords, _ = t_path.get_transformed_path_and_affine()
In [11]: path_in_data_coords.vertices
Out[11]:
array([[-6425061.82215208, 4594257.92617961],
[-5808923.84969279, 5250795.00604155],
[-5206753.88613758, 5777772.51828996],
[-4554622.94040482, 6244967.03723341],
[-3887558.58343227, 6627927.97123701],
[-3200922.19194864, 6932398.19937816],
[-2480001.76507805, 7165675.95095855],
[-1702269.5101901 , 7332885.72276795],
[ -859899.12295981, 7431215.78426759],
[ 23837.23431173, 7453455.61302756],
[ 889905.10635756, 7397128.77301289],
[ 1695586.66856764, 7268519.87627204],
[ 2434052.81300274, 7073912.54130764],
[ 3122221.22299409, 6812894.40443648],
[ 3782033.80448001, 6478364.28561403],
[ 4425266.18173684, 6062312.15662039],
[ 5049148.25986903, 5563097.6328901 ],
[ 5616318.74912886, 5008293.21452795],
[ 6213232.98764984, 4307186.23400115],
[ 6720608.93929235, 3584542.06839575],
[ 7034261.06659143, 3059873.62740856]])
We can pull this together with matplotlib's animation functionality to do as requested:
import cartopy.crs as ccrs
import matplotlib.animation as animation
import matplotlib.pyplot as plt
ax = plt.axes(projection=ccrs.Robinson())
ax.stock_img()
ny_lon, ny_lat = -75, 43
delhi_lon, delhi_lat = 77.23, 28.61
[line] = plt.plot([ny_lon, delhi_lon], [ny_lat, delhi_lat],
color='blue', linewidth=2, marker='o',
transform=ccrs.Geodetic(),
)
t_path = line._get_transformed_path()
path_in_data_coords, _ = t_path.get_transformed_path_and_affine()
# Draw the point that we want to animate.
[point] = plt.plot(ny_lon, ny_lat, marker='o', transform=ax.projection)
def animate_point(i):
verts = path_in_data_coords.vertices
i = i % verts.shape[0]
# Set the coordinates of the line to the coordinate of the path.
point.set_data(verts[i, 0], verts[i, 1])
ani = animation.FuncAnimation(
ax.figure, animate_point,
frames= path_in_data_coords.vertices.shape[0],
interval=125, repeat=True)
ani.save('point_ani.gif', writer='imagemagick')
plt.show()
The cartopy approach
Under the hood, cartopy's matplotlib implementation (as used above), is calling the project_geometry method. We may as well make use of this directly as it is often more convenient to be using Shapely geometries than it is matplotlib Paths.
With this approach, we simply define a shapely geometry, and then construct the source and target coordinate reference systems that we want to convert the geometry from/to:
target_cs.project_geometry(geometry, source_cs)
The only thing we have to watch out for is that the result can be a MultiLineString (or more generally, any Multi- geometry type). However, in our simple case, we don't need to deal with that (incidentally, the same was true of the simple Path returned in the first example).
The code to produce a similar plot to above:
import cartopy.crs as ccrs
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
import shapely.geometry as sgeom
ax = plt.axes(projection=ccrs.Robinson())
ax.stock_img()
ny_lon, ny_lat = -75, 43
delhi_lon, delhi_lat = 77.23, 28.61
line = sgeom.LineString([[ny_lon, ny_lat], [delhi_lon, delhi_lat]])
projected_line = ccrs.PlateCarree().project_geometry(line, ccrs.Geodetic())
# We only animate along one of the projected lines.
if isinstance(projected_line, sgeom.MultiLineString):
projected_line = projected_line.geoms[0]
ax.add_geometries(
[projected_line], ccrs.PlateCarree(),
edgecolor='blue', facecolor='none')
[point] = plt.plot(ny_lon, ny_lat, marker='o', transform=ccrs.PlateCarree())
def animate_point(i):
verts = np.array(projected_line.coords)
i = i % verts.shape[0]
# Set the coordinates of the line to the coordinate of the path.
point.set_data(verts[i, 0], verts[i, 1])
ani = animation.FuncAnimation(
ax.figure, animate_point,
frames=len(projected_line.coords),
interval=125, repeat=True)
ani.save('projected_line_ani.gif', writer='imagemagick')
plt.show()
Final remaaaaarrrrrrks....
The approach naturally generalises to animating any type of matplotlib Arrrrtist.... in this case, I took a bit more control over the great circle resolution, and I animated an image along the great circle:
import cartopy.crs as ccrs
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
import shapely.geometry as sgeom
ax = plt.axes(projection=ccrs.Mercator())
ax.stock_img()
line = sgeom.LineString([[-5.9845, 37.3891], [-82.3666, 23.1136]])
# Higher resolution version of Mercator. Same workaround as found in
# https://github.com/SciTools/cartopy/issues/8#issuecomment-326987465.
class HighRes(ax.projection.__class__):
#property
def threshold(self):
return super(HighRes, self).threshold / 100
projected_line = HighRes().project_geometry(line, ccrs.Geodetic())
# We only animate along one of the projected lines.
if isinstance(projected_line, sgeom.MultiLineString):
projected_line = projected_line.geoms[0]
# Add the projected line to the map.
ax.add_geometries(
[projected_line], ax.projection,
edgecolor='blue', facecolor='none')
def ll_to_extent(x, y, ax_size=(4000000, 4000000)):
"""
Return an image extent in centered on the given
point with the given width and height.
"""
return [x - ax_size[0] / 2, x + ax_size[0] / 2,
y - ax_size[1] / 2, y + ax_size[1] / 2]
# Image from https://pixabay.com/en/sailing-ship-boat-sail-pirate-28930/.
pirate = plt.imread('pirates.png')
img = ax.imshow(pirate, extent=ll_to_extent(0, 0), transform=ax.projection, origin='upper')
ax.set_global()
def animate_ship(i):
verts = np.array(projected_line.coords)
i = i % verts.shape[0]
# Set the extent of the image to the coordinate of the path.
img.set_extent(ll_to_extent(verts[i, 0], verts[i, 1]))
ani = animation.FuncAnimation(
ax.figure, animate_ship,
frames=len(projected_line.coords),
interval=125, repeat=False)
ani.save('arrrr.gif', writer='imagemagick')
plt.show()
All code and images for this answer can be found at https://gist.github.com/pelson/618a5f4ca003e56f06d43815b21848f6.

Straight line through the pole with Cartopy stereographic projection

I'm using cartopy to produce a map of the Arctic with stereographic projection and then plotting a line (to show the position of a cross-section) over the top. If I use the following code then the line doesn't go in a straight line through the pole but instead goes along a line of latitude.
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
x=[180,0]
y=[50,50]
ax = plt.axes(projection=ccrs.NorthPolarStereo())
ax.set_extent([0, 360, 50, 90], crs=ccrs.PlateCarree())
ax.plot(x,y,transform=ccrs.PlateCarree())
plt.gca().stock_img()
plt.gca().coastlines()
plt.show()
To get round this I have to change x and y to:
x=[180,180,0,0]
y=[50,90,90,50]
so that there are two data points at the North Pole. Is there a better solution for this?
Edit: Image attached
Thanks,
Tim
#ajdawson's answer is correct. Using the Geodetic transform, in this case, will do the trick.
To understand the reason the line wasn't as you expected it to look, we need to understand what the PlateCarree transform represents.
Firstly, lets observe that all lines drawn in the transform=<projection> form, using Cartopy, should pass through the same Geographic points irrespective of the projection that the line is being drawn on.
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
def main():
x=[180, 180, 0, 0]
y=[50, 90, 90, 50]
# plot2 - North Polar Stereographic
ax = plt.subplot(211, projection=ccrs.NorthPolarStereo())
ax.set_extent([0, 360, 50, 90], crs=ccrs.PlateCarree())
ax.plot(x, y, transform=ccrs.PlateCarree(), color='red', lw=2)
ax.stock_img()
ax.coastlines()
# plot2 - PlateCarree
ax = plt.subplot(212, projection=ccrs.PlateCarree(central_longitude=45))
ax.set_extent([0, 360, -45, 90], crs=ccrs.PlateCarree())
ax.plot(x, y, transform=ccrs.PlateCarree(), color='red', lw=2)
ax.stock_img()
ax.coastlines()
plt.show()
if __name__ == '__main__':
main()
So going back to drawing your original coordinates (which were in PlateCarree coordinates) on a PlateCarree map:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
def main():
x=[180, 0]
y=[50, 50]
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=45))
ax.set_extent([0, 360, -45, 90], crs=ccrs.PlateCarree())
ax.plot(x, y, transform=ccrs.PlateCarree(), color='red', lw=2)
ax.stock_img()
ax.coastlines()
plt.tight_layout()
plt.show()
if __name__ == '__main__':
main()
You will find that the line passes through the same geographic points as your bad line in the original question.
This should satisfy you that Cartopy is behaving rationally and it is not a bug, but it doesn't answer the question about how you would go about drawing the line you desire.
#ajdawson has already said that, in your case, drawing the line:
plt.plot([180, 0], [50, 50] , transform=ccrs.Geodetic())
will result in the desired output.
That is because the Geodetic coordinate reference system draws the line of shortest distance on the globe between two points. However, there will be a latitude which, when crossed, passing through the north pole does not provide the shortest distance:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
def main():
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=45))
ax.set_global()
ax.plot([180, 0], [20, 20], transform=ccrs.Geodetic(), color='red', lw=2, label='Latitude = 20')
ax.plot([180, 0], [0, 0], transform=ccrs.Geodetic(), color='blue', lw=2, label='Latitude = 0')
ax.plot([180, 0], [-20, -20], transform=ccrs.Geodetic(), color='yellow', lw=2, label='Latitude = -20')
ax.outline_patch.set_zorder(2)
plt.legend(loc=8, bbox_to_anchor=(0.65, -0.2), shadow=True, fancybox=True)
ax.stock_img()
ax.coastlines()
plt.tight_layout()
plt.show()
if __name__ == '__main__':
main()
Generally, if you wanted to draw a Geodetic line which always crosses the North Pole, then the north pole should be one of the coordinates of the line.
plt.plot([180, 0, 0], [-45, 90, -45] , transform=ccrs.Geodetic())
Finally, just to throw it into the mix, if you just wanted a vertical line in a North Polar Stereographic projection which crosses the North Pole, it is worth remembering that there exists a Cartesian coordinate system (in which it is worth remembering that the numbers are not latitude and longitudes), so simply doing:
ax = plt.axes(projection=ccrs.NorthPolarStereo())
plt.axvline()
Will also do the trick! (but is less transferable than the Geodetic approach)
Wow, my answer got long. I hope your still with me and that makes the whole PlateCarree thing clearer!
I think you need to use the Geodetic transform when plotting this section rather than Plate Carree:
<!-- language: lang-py -->
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
x=[180,0]
y=[50,50]
ax = plt.axes(projection=ccrs.NorthPolarStereo())
ax.set_extent([0, 360, 50, 90], crs=ccrs.PlateCarree())
ax.plot(x,y,transform=ccrs.Geodetic())
ax.stock_img()
ax.coastlines()
plt.show()
The result looks like this:
I think that is the correct way to handle this anyway!
Andrew

Setting up a map which crosses the dateline in cartopy

I received the following email and wanted to make sure the answer to this question was available to everybody:
Hi,
I would like to setup a simple latitude longitude map, using cartopy, which crosses the dateline and shows east Asia on the left hand side with the west of North America on the right. The following google map is roughly what I am after:
https://maps.google.co.uk/?ll=56.559482,-175.253906&spn=47.333523,133.066406&t=m&z=4
Can this be done with Cartopy?
Good question. This is probably something which will come up time-and-time again, so I will go through this step-by-step before actually answering your specific question. For future reference, the following examples were written with cartopy v0.5.
Firstly, it is important to note that the default "latitude longitude" (or more technically PlateCarree) projection works in the forward range of -180 to 180. This means that you cannot plot the standard PlateCarree projection beyond this. There are several good reasons for this, most of which boil down to the fact that cartopy would have to do a lot more work when projecting both vectors and rasters (simple coastlines for example). Unfortunately the plot you are trying to produce requires precisely this functionality. To put this limitation into pictures, the default PlateCarree projection looks like:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
proj = ccrs.PlateCarree(central_longitude=0)
ax1 = plt.axes(projection=proj)
ax1.stock_img()
plt.title('Global')
plt.show()
Any single rectangle that you can draw on this map can legally be a zoomed in area (there is some slightly more advanced code in here, but the picture is worth a 1000 words):
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import shapely.geometry as sgeom
box = sgeom.box(minx=-90, maxx=45, miny=15, maxy=70)
x0, y0, x1, y1 = box.bounds
proj = ccrs.PlateCarree(central_longitude=0)
ax1 = plt.subplot(211, projection=proj)
ax1.stock_img()
ax1.add_geometries([box], proj, facecolor='coral',
edgecolor='black', alpha=0.5)
plt.title('Global')
ax2 = plt.subplot(212, projection=proj)
ax2.stock_img()
ax2.set_extent([x0, x1, y0, y1], proj)
plt.title('Zoomed in area')
plt.show()
Unfortunately the plot you want would require 2 rectangles with this projection:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import shapely.geometry as sgeom
box = sgeom.box(minx=120, maxx=260, miny=15, maxy=80)
proj = ccrs.PlateCarree(central_longitude=0)
ax1 = plt.axes(projection=proj)
ax1.stock_img()
ax1.add_geometries([box], proj, facecolor='coral',
edgecolor='black', alpha=0.5)
plt.title('Target area')
plt.show()
Hence it is not possible to draw a map that crosses the dateline using the standard PlateCarree definition. Instead we could change the PlateCarree definition's central longitude to allow a single box to be drawn of the area we are targeting:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import shapely.geometry as sgeom
box = sgeom.box(minx=120, maxx=260, miny=15, maxy=80)
x0, y0, x1, y1 = box.bounds
proj = ccrs.PlateCarree(central_longitude=180)
box_proj = ccrs.PlateCarree(central_longitude=0)
ax1 = plt.subplot(211, projection=proj)
ax1.stock_img()
ax1.add_geometries([box], box_proj, facecolor='coral',
edgecolor='black', alpha=0.5)
plt.title('Global')
ax2 = plt.subplot(212, projection=proj)
ax2.stock_img()
ax2.set_extent([x0, x1, y0, y1], box_proj)
plt.title('Zoomed in area')
plt.show()
Hopefully that shows you what it is you have to do to achieve your target map, the code above might be a little complex to achieve your goal, so to simplify slightly, the code I would write to produce the plot you want would be something like:
import cartopy.feature
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=180))
ax.set_extent([120, 260, 15, 80], crs=ccrs.PlateCarree())
# add some features to make the map a little more polished
ax.add_feature(cartopy.feature.LAND)
ax.add_feature(cartopy.feature.OCEAN)
ax.coastlines('50m')
plt.show()
This was a long answer, hopefully I have not only answered the question, but made some of the more complex details of map production and cartopy more clear to help smooth any future problems you may have.
Cheers,
For more details of above benjimin's comment,
import numpy as np
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.mpl.gridliner import LONGITUDE_FORMATTER, LATITUDE_FORMATTER
from matplotlib.ticker import AutoMinorLocator, FixedLocator, MultipleLocator
def map_common(ax1,gl_loc=[True,True,False,True],gl_lon_info=range(-180,180,60),gl_dlat=30):
ax1.coastlines(color='silver',linewidth=1.)
gl = ax1.gridlines(crs=ccrs.PlateCarree(), draw_labels=True,
linewidth=0.6, color='gray', alpha=0.5, linestyle='--')
gl.ylabels_left = gl_loc[0]
gl.ylabels_right = gl_loc[1]
gl.xlabels_top = gl_loc[2]
gl.xlabels_bottom = gl_loc[3]
gl.xlocator = FixedLocator(gl_lon_info)
gl.ylocator = MultipleLocator(gl_dlat)
gl.xformatter = LONGITUDE_FORMATTER
gl.yformatter = LATITUDE_FORMATTER
gl.xlabel_style = {'size': 11, 'color': 'k'}
gl.ylabel_style = {'size': 11, 'color': 'k'}
lon_boundary=np.arange(-240,-60,1.)
lat_boundary=np.arange(15,75,1.)
data=np.ones([lat_boundary.shape[0]-1,lon_boundary.shape[0]-1]) ## Data dimension is 1 less than boundaries
data=data*lat_boundary[:-1,None]
lon_offset=-150 ##
x,y=np.meshgrid(lon_boundary-lon_offset,lat_boundary)
fig=plt.figure()
fig.set_size_inches(7.5,5) ## (xsize, ysize)
ax1=fig.add_subplot(111,projection=ccrs.PlateCarree(central_longitude=lon_offset))
ax1.set_extent([-250,-50,10,80],crs=ccrs.PlateCarree())
props=dict(vmin=0,vmax=90,cmap=plt.cm.get_cmap('bone'),alpha=0.8)
cs=ax1.pcolormesh(x,y,data,**props)
ax1.set_title('Lon_Offset=-90')
map_common(ax1,gl_lon_info=[-180,-120,-60,120,],gl_dlat=15)
fnout='./map_over_dateline.png'
#plt.show()
plt.savefig(fnout,bbox_inches='tight',dpi=150)
Output of this program