def test_LongitudeFormatter_central_longitude_180(): formatter = LongitudeFormatter(zero_direction_label=True) p = ccrs.PlateCarree(central_longitude=180) formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-180, -120, -60, 0, 60, 120, 180] result = [formatter(tick) for tick in test_ticks] expected = [u'0\u00B0E', u'60\u00B0E', u'120\u00B0E', u'180\u00B0', u'120\u00B0W', u'60\u00B0W', u'0\u00B0W'] assert_equal(result, expected)
def test_LongitudeFormatter_central_longitude_120(): formatter = LongitudeFormatter() p = ccrs.PlateCarree(central_longitude=120) formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-180, -120, -60, 0, 60, 120, 180] result = [formatter(tick) for tick in test_ticks] expected = [u'60\u00B0W', u'0\u00B0', u'60\u00B0E', u'120\u00B0E', u'180\u00B0', u'120\u00B0W', u'60\u00B0W'] assert result == expected
def test_LongitudeFormatter_small_numbers_0(): formatter = LongitudeFormatter(number_format='.7f') p = ccrs.PlateCarree(central_longitude=0) formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-17.1142343, -17.1142340, -17.1142337] result = [formatter(tick) for tick in test_ticks] expected = [u'17.1142343\u00B0W', u'17.1142340\u00B0W', u'17.1142337\u00B0W'] assert result == expected
def test_LongitudeFormatter_degree_symbol(): formatter = LongitudeFormatter(degree_symbol='', dateline_direction_label=True) p = ccrs.PlateCarree() formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-180, -120, -60, 0, 60, 120, 180] result = [formatter(tick) for tick in test_ticks] expected = [u'180W', u'120W', u'60W', u'0', u'60E', u'120E', u'180E'] assert result == expected
def test_LongitudeFormatter_small_numbers_180(): formatter = LongitudeFormatter(zero_direction_label=True, number_format='.7f') p = ccrs.PlateCarree(central_longitude=180) formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-17.1142343, -17.1142340, -17.1142337] result = [formatter(tick) for tick in test_ticks] expected = [u'162.8857657\u00B0E', u'162.8857660\u00B0E', u'162.8857663\u00B0E'] assert result == expected
def test_LongitudeFormatter_mercator(): formatter = LongitudeFormatter(dateline_direction_label=True) p = ccrs.Mercator() formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-20037508.342783064, -13358338.895188706, -6679169.447594353, 0.0, 6679169.447594353, 13358338.895188706, 20037508.342783064] result = [formatter(tick) for tick in test_ticks] expected = [u'180\u00B0W', u'120\u00B0W', u'60\u00B0W', u'0\u00B0', u'60\u00B0E', u'120\u00B0E', u'180\u00B0E'] assert result == expected
def test_LongitudeFormatter_number_format(): formatter = LongitudeFormatter(number_format='.2f', dateline_direction_label=True) p = ccrs.PlateCarree() formatter.axis = Mock(axes=Mock(GeoAxes, projection=p)) test_ticks = [-180, -120, -60, 0, 60, 120, 180] result = [formatter(tick) for tick in test_ticks] expected = [u'180.00\u00B0W', u'120.00\u00B0W', u'60.00\u00B0W', u'0.00\u00B0', u'60.00\u00B0E', u'120.00\u00B0E', u'180.00\u00B0E'] assert result == expected
def __init__(self, axes, crs, draw_labels=False, xlocator=None, ylocator=None, collection_kwargs=None, xformatter=None, yformatter=None, dms=False, x_inline=None, y_inline=None, auto_inline=True): """ Object used by :meth:`cartopy.mpl.geoaxes.GeoAxes.gridlines` to add gridlines and tick labels to a map. Parameters ---------- axes The :class:`cartopy.mpl.geoaxes.GeoAxes` object to be drawn on. crs The :class:`cartopy.crs.CRS` defining the coordinate system that the gridlines are drawn in. draw_labels: optional Toggle whether to draw labels. For finer control, attributes of :class:`Gridliner` may be modified individually. Defaults to False. xlocator: optional A :class:`matplotlib.ticker.Locator` instance which will be used to determine the locations of the gridlines in the x-coordinate of the given CRS. Defaults to None, which implies automatic locating of the gridlines. ylocator: optional A :class:`matplotlib.ticker.Locator` instance which will be used to determine the locations of the gridlines in the y-coordinate of the given CRS. Defaults to None, which implies automatic locating of the gridlines. xformatter: optional A :class:`matplotlib.ticker.Formatter` instance to format labels for x-coordinate gridlines. It defaults to None, which implies the use of a :class:`cartopy.mpl.ticker.LongitudeFormatter` initiated with the ``dms`` argument, if the crs is of :class:`~cartopy.crs.PlateCarree` type. yformatter: optional A :class:`matplotlib.ticker.Formatter` instance to format labels for y-coordinate gridlines. It defaults to None, which implies the use of a :class:`cartopy.mpl.ticker.LatitudeFormatter` initiated with the ``dms`` argument, if the crs is of :class:`~cartopy.crs.PlateCarree` type. collection_kwargs: optional Dictionary controlling line properties, passed to :class:`matplotlib.collections.Collection`. Defaults to None. dms: bool When default locators and formatters are used, ticks are able to stop on minutes and seconds if minutes is set to True, and not fraction of degrees. x_inline: optional Toggle whether the x labels drawn should be inline. y_inline: optional Toggle whether the y labels drawn should be inline. auto_inline: optional Set x_inline and y_inline automatically based on projection. Notes ----- The "x" and "y" labels for locators and formatters do not necessarily correspond to X and Y, but to the first and second coordinates of the specified CRS. For the common case of PlateCarree gridlines, these correspond to longitudes and latitudes. Depending on the projection used for the map, meridians and parallels can cross both the X axis and the Y axis. """ self.axes = axes #: The :class:`~matplotlib.ticker.Locator` to use for the x #: gridlines and labels. if xlocator is not None: if not isinstance(xlocator, mticker.Locator): xlocator = mticker.FixedLocator(xlocator) self.xlocator = xlocator elif isinstance(crs, cartopy.crs.PlateCarree): self.xlocator = LongitudeLocator(dms=dms) else: self.xlocator = classic_locator #: The :class:`~matplotlib.ticker.Locator` to use for the y #: gridlines and labels. if ylocator is not None: if not isinstance(ylocator, mticker.Locator): ylocator = mticker.FixedLocator(ylocator) self.ylocator = ylocator elif isinstance(crs, cartopy.crs.PlateCarree): self.ylocator = LatitudeLocator(dms=dms) else: self.ylocator = classic_locator if xformatter is None: if isinstance(crs, cartopy.crs.PlateCarree): xformatter = LongitudeFormatter(dms=dms) else: xformatter = classic_formatter() #: The :class:`~matplotlib.ticker.Formatter` to use for the lon labels. self.xformatter = xformatter if yformatter is None: if isinstance(crs, cartopy.crs.PlateCarree): yformatter = LatitudeFormatter(dms=dms) else: yformatter = classic_formatter() #: The :class:`~matplotlib.ticker.Formatter` to use for the lat labels. self.yformatter = yformatter #: Whether to draw labels on the top of the map. self.top_labels = draw_labels #: Whether to draw labels on the bottom of the map. self.bottom_labels = draw_labels #: Whether to draw labels on the left hand side of the map. self.left_labels = draw_labels #: Whether to draw labels on the right hand side of the map. self.right_labels = draw_labels if auto_inline: if isinstance(self.axes.projection, _X_INLINE_PROJS): self.x_inline = True self.y_inline = False elif isinstance(self.axes.projection, _POLAR_PROJS): self.x_inline = False self.y_inline = True else: self.x_inline = False self.y_inline = False # overwrite auto_inline if necessary if x_inline is not None: #: Whether to draw x labels inline self.x_inline = x_inline elif not auto_inline: self.x_inline = False if y_inline is not None: #: Whether to draw y labels inline self.y_inline = y_inline elif not auto_inline: self.y_inline = False #: Whether to draw the x gridlines. self.xlines = True #: Whether to draw the y gridlines. self.ylines = True #: A dictionary passed through to ``ax.text`` on x label creation #: for styling of the text labels. self.xlabel_style = {} #: A dictionary passed through to ``ax.text`` on y label creation #: for styling of the text labels. self.ylabel_style = {} #: The padding from the map edge to the x labels in points. self.xpadding = 5 #: The padding from the map edge to the y labels in points. self.ypadding = 5 #: Allow the rotation of labels. self.rotate_labels = True # Current transform self.crs = crs # if the user specifies tick labels at this point, check if they can # be drawn. The same check will take place at draw time in case # public attributes are changed after instantiation. if draw_labels and not (x_inline or y_inline or auto_inline): self._assert_can_draw_ticks() #: The number of interpolation points which are used to draw the #: gridlines. self.n_steps = 100 #: A dictionary passed through to #: ``matplotlib.collections.LineCollection`` on grid line creation. self.collection_kwargs = collection_kwargs #: The x gridlines which were created at draw time. self.xline_artists = [] #: The y gridlines which were created at draw time. self.yline_artists = [] # Plotted status self._plotted = False # Check visibility of labels at each draw event # (or once drawn, only at resize event ?) self.axes.figure.canvas.mpl_connect('draw_event', self._draw_event)
def test_LongitudeFormatter_minutes_seconds(test_ticks, expected): formatter = LongitudeFormatter(dms=True, auto_hide=True) formatter.set_locs(test_ticks) result = [formatter(tick) for tick in test_ticks] assert result == expected
def map(self): import matplotlib.pyplot as plt import seaborn as sns import cartopy.crs as ccrs from cartopy.mpl.ticker import LongitudeFormatter, LatitudeFormatter print("Plotting global distribution of samples...") dlon, dlat = 2.5, 1.9 npoints = len(self._df) df_map = self._df.copy() def rand_fact(npoints, width): """ Rescale a number from [0, 1) to [-width, width) """ points = 2. * np.random.random(npoints) - 1. points *= width return points l1 = df_map['lon'].copy() l2 = df_map['lat'].copy() df_map['lon'] = df_map['lon'] + rand_fact(npoints, dlon / 2.) df_map['lat'] = df_map['lat'] + rand_fact(npoints, dlat / 2.) lon, lat = df_map.lon, df_map.lat # Correct lon: # 1) some values may be < 0 or > 360, map these into [0, 360] lon[lon < 0] = lon[lon < 0] + 360. lon[lon > 360] = lon[lon > 360] - 360. # 2) map from [0, 360] -> [-180, 180] lon -= 180. df_map['lon'] = lon[:] proj = ccrs.PlateCarree() cmap = sns.light_palette("navy", 12, as_cmap=True) fig, ax = plt.subplots(1, 1, figsize=(10, 5), subplot_kw=dict(projection=proj)) cax = fig.add_axes([0, 0, 0.1, 0.1]) fig.subplots_adjust(hspace=0, wspace=0, top=0.925, left=0.1) hb = ax.hexbin(lon, lat, gridsize=(50, 15), bins='log', transform=proj, cmap=cmap) # This block of code helps correctly size and place the colorbar def resize_colorbar(event): plt.draw() posn = ax.get_position() cax.set_position( [posn.x0 + posn.width + 0.01, posn.y0, 0.04, posn.height]) fig.canvas.mpl_connect('resize_event', resize_colorbar) ax.coastlines() ax.set_global() ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=proj) ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=proj) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) plt.colorbar(hb, cax, ax) plt.show()
def test_LongitudeFormatter_bad_projection(): formatter = LongitudeFormatter() formatter.axis = Mock(axes=Mock(GeoAxes, projection=ccrs.Orthographic())) match = r'This formatter cannot be used with non-rectangular projections\.' with pytest.raises(TypeError, match=match): formatter(0)
'omip1mean': (['model', 'lat', 'lon'], d_tmp3), 'omip2mean': (['model', 'lat', 'lon'], d_tmp4), 'omip2-1': (['model', 'lat', 'lon'], d_tmp4 - d_tmp3), 'obs': (['lat', 'lon'], da0.values), }, coords={ 'lat': np.linspace(-89.5, 89.5, num=180), 'lon': np.linspace(0.5, 359.5, num=360), }) #J 描画 fig = plt.figure(figsize=(11, 8)) fig.suptitle(suptitle, fontsize=18) proj = ccrs.PlateCarree(central_longitude=-140.) lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax = [ plt.subplot(3, 2, 1, projection=proj), plt.subplot(3, 2, 2, projection=proj), plt.subplot(3, 2, 3, projection=proj), plt.subplot(3, 2, 4, projection=proj), plt.subplot(3, 2, 5, projection=proj), plt.subplot(3, 2, 6), ] bounds1 = [ -1.0, -0.7, -0.5, -0.3, -0.2, -0.1, -0.05, 0., 0.05, 0.1, 0.2, 0.3, 0.5, 0.7, 1.0 ]
def plot_panel(n, fig, proj, var, clevels, cmap, title, parameters, stats=None): # var_min = float(var.min()) # var_max = float(var.max()) # var_mean = cdutil.averager(var, axis='xy', weights='generate') # var = add_cyclic(var) lon = var.getLongitude() lat = var.getLatitude() plev = var.getLevel() var = ma.squeeze(var.asma()) # Contour levels levels = None norm = None if len(clevels) > 0: levels = [-1.0e8] + clevels + [1.0e8] norm = colors.BoundaryNorm(boundaries=levels, ncolors=256) # Contour plot ax = fig.add_axes(panel[n], projection=proj) cmap = get_colormap(cmap, parameters) p1 = ax.contourf( lat, plev, var, # transform=ccrs.PlateCarree(), norm=norm, levels=levels, cmap=cmap, extend='both', ) ax.set_aspect('auto') # ax.coastlines(lw=0.3) if title[0] != None: ax.set_title(title[0], loc='left', fontdict=plotSideTitle) if title[1] != None: ax.set_title(title[1], fontdict=plotTitle) if title[2] != None: ax.set_title(title[2], loc='right', fontdict=plotSideTitle) #ax.set_xticks([0, 60, 120, 180, 240, 300, 359.99], crs=ccrs.PlateCarree()) #ax.set_xticks([-180, -120, -60, 0, 60, 120, 180], crs=ccrs.PlateCarree()) ax.set_xticks([-90, -60, -30, 0, 30, 60, 90]) #, crs=ccrs.PlateCarree()) ax.set_xlim(-90, 90) lon_formatter = LongitudeFormatter(zero_direction_label=True, number_format='.0f') lat_formatter = LatitudeFormatter() #ax.xaxis.set_major_formatter(lon_formatter) #ax.xaxis.set_major_formatter(lat_formatter) ax.tick_params(labelsize=8.0, direction='out', width=1) ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') ax.invert_yaxis() # Color bar cbax = fig.add_axes( (panel[n][0] + 0.6635, panel[n][1] + 0.0215, 0.0326, 0.1792)) cbar = fig.colorbar(p1, cax=cbax) w, h = get_ax_size(fig, cbax) if levels == None: cbar.ax.tick_params(labelsize=9.0, length=0) else: maxval = np.amax(np.absolute(levels[1:-1])) if maxval < 10.0: fmt = "%5.2f" pad = 25 elif maxval < 100.0: fmt = "%5.1f" pad = 25 else: fmt = "%6.1f" pad = 30 cbar.set_ticks(levels[1:-1]) labels = [fmt % l for l in levels[1:-1]] cbar.ax.set_yticklabels(labels, ha='right') cbar.ax.tick_params(labelsize=9.0, pad=pad, length=0) # Min, Mean, Max fig.text(panel[n][0] + 0.6635, panel[n][1] + 0.2107, "Max\nMean\nMin", ha='left', fontdict=plotSideTitle) fig.text(panel[n][0] + 0.7635, panel[n][1] + 0.2107, "%.2f\n%.2f\n%.2f" % stats[0:3], ha='right', fontdict=plotSideTitle) # RMSE, CORR if len(stats) == 5: fig.text(panel[n][0] + 0.6635, panel[n][1] - 0.0105, "RMSE\nCORR", ha='left', fontdict=plotSideTitle) fig.text(panel[n][0] + 0.7635, panel[n][1] - 0.0105, "%.2f\n%.2f" % stats[3:5], ha='right', fontdict=plotSideTitle)
def test_LongitudeFormatter_bad_axes(): formatter = LongitudeFormatter() formatter.axis = Mock(axes=Mock(Axes, projection=ccrs.PlateCarree())) message = 'This formatter can only be used with cartopy axes.' with pytest.raises(TypeError, message=message): formatter(0)
def test_LongitudeFormatter_bad_projection(): formatter = LongitudeFormatter() formatter.axis = Mock(axes=Mock(GeoAxes, projection=ccrs.Orthographic())) message = 'This formatter cannot be used with non-rectangular projections.' with assert_raises_regexp(TypeError, message): formatter(0)
levels = np.linspace(-100,100,51), extend = 'both', cmap = cmocean.cm.balance, projection=ccrs.PlateCarree()) #add colorbar cb1 = fig.colorbar(contf1, ticks = np.linspace(-100,100,11), format = '%.0f', orientation = 'horizontal',fraction=0.08, pad=0.15) #set colorbar format cb1.set_label('cm/year', fontsize = 16) cb1.ax.tick_params(labelsize=16) #set ax1 label's and tick's format ax1.set_xticks([ -180, -120, -60,0, 60, 120, 180,], crs=ccrs.PlateCarree()) ax1.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree()) ax1.tick_params(axis='both', labelsize=20) ax1.xaxis.set_major_formatter(LongitudeFormatter()) ax1.yaxis.set_major_formatter(LatitudeFormatter()) ##plot ax2, temporal change of zonal average evaporation ax2 = fig.add_subplot(grid[0,2]) t = -time_lgm[0] ax2.plot(prect_zonal[0,:], lat, linewidth=3.0, color = 'b', linestyle = '--', label='%.2f ky BP' %t) ax2.plot(prect_1850_1980_zonal, lat, linewidth = 2.0, color = 'r', label = '1850-1980 AD') #set ax2 format ax2.set_ylabel('°N',fontsize = 16) ax2.tick_params(labelsize=16) ax2.set_xlabel("cm/year",fontsize = 16) ax2.set_xlim([0,240]) ax2.legend(fontsize = 12) #animate the plot with temporal change
def PlotCompositesDivPlumbPV(var_pos, var_neg, u_pos, u_neg, v_pos, v_neg, lat, lon, title, filename): proj = ccrs.PlateCarree(central_longitude=180) fig = plt.figure(1, (10, 6.7), 300) ax = plt.subplot(2, 1, 1, projection=proj) clevs = np.arange(-1.2, 1.6, 0.8) barra = plt.cm.RdBu_r ax.set_extent([0, 359, -90, 0], crs=ccrs.PlateCarree()) im = ax.contourf(lon, lat, var_pos / 10, clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-1.2, vmax=1.2) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) M = np.sqrt(np.add(np.power(u_pos, 2), np.power(v_pos, 2))) < 0.3 #mask array u_mask = ma.array(u_pos, mask=M) v_mask = ma.array(v_pos, mask=M) ax.quiver( lon[0:-1:6], lat[0:-1:6], u_mask[0:-1:6, 0:-1:6], v_mask[0:-1:6, 0:-1:6], transform=ccrs.PlateCarree(), angles='xy' ) #, headwidth=2.8, headlength=1.8, width=1.5e-3, headaxislength=2.8) ax.coastlines() ax.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) ax.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) plt.title('Strong PV YEARS') ax1 = plt.subplot(2, 1, 2, projection=proj) ax1.set_extent([0, 359, -90, 0], crs=ccrs.PlateCarree()) im = ax1.contourf(lon, lat, var_neg / 10, clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-1.2, vmax=1.2) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) M = np.sqrt(np.add(np.power(u_neg, 2), np.power(v_neg, 2))) < 0.3 #mask array u_mask = ma.array(u_neg, mask=M) v_mask = ma.array(v_neg, mask=M) ax1.quiver( lon[0:-1:6], lat[0:-1:6], u_mask[0:-1:6, 0:-1:6], v_mask[0:-1:6, 0:-1:6], transform=ccrs.PlateCarree(), angles='xy' ) #, headwidth=2.8, headlength=1.8, width=1.5e-3, headaxislength=2.8) ax1.coastlines() ax1.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) #countries ax1.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax1.xaxis.set_major_formatter(lon_formatter) ax1.yaxis.set_major_formatter(lat_formatter) plt.title('Weak PV YEARS') plt.suptitle(title, fontsize=12, x=0.47, y=0.9) fig.subplots_adjust(right=0.8) fig.subplots_adjust(bottom=0.17, top=0.82, hspace=0.2, wspace=0.05) cbar_ax = fig.add_axes([0.33, 0.1, 0.25, 0.05]) fig.colorbar(im, cax=cbar_ax, orientation='horizontal') plt.savefig(filename, dpi=300, bbox_inches='tight', orientation='landscape', papertype='A4') plt.clf() plt.cla() plt.close()
def PlotPoVCompositesDiffENSOZPF(var, lat, lon, title, filename): var_keys = [*var] #print(var_keys) tit = ['All', 'El Ninio', 'La Ninia'] proj = ccrs.PlateCarree(central_longitude=180) fig = plt.figure(1, (10, 6.7), 300) for i in range(3): ax = plt.subplot(3, 1, i + 1, projection=proj) clevs = np.arange(-60, 70, 10) barra = plt.cm.RdBu_r ax.set_extent([0, 359, -90, 20], crs=ccrs.PlateCarree()) im = ax.contourf(lon, lat, var[var_keys[i * 3]], clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-60, vmax=60) lat1 = lat[lat < 0] u = var[var_keys[i * 3 + 1]][lat1 < -18, :] v = var[var_keys[i * 3 + 2]][lat1 < -18, :] lat1 = lat1[lat1 < -18] M = np.sqrt(np.add(np.power(u, 2), np.power(v, 2))) < 0.07 #mask array u_mask = ma.array(u, mask=M) v_mask = ma.array(v, mask=M) ax.quiver(lon[2:-1:6], lat1[2:-1:6], u_mask[2:-1:6, 2:-1:6], v_mask[2:-1:6, 2:-1:6], transform=ccrs.PlateCarree(), angles='xy', headwidth=2.8, headlength=1.8, width=1.5e-3, headaxislength=2.8) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) ax.coastlines() ax.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) ax.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) plt.title(tit[i]) plt.suptitle(title, fontsize=12, x=0.47, y=0.9) fig.subplots_adjust(right=0.8) fig.subplots_adjust(bottom=0.17, top=0.82, hspace=0.2, wspace=0.05) cbar_ax = fig.add_axes([0.33, 0.1, 0.25, 0.05]) fig.colorbar(im, cax=cbar_ax, orientation='horizontal') plt.savefig(filename, dpi=300, bbox_inches='tight', orientation='landscape', papertype='A4') plt.clf() plt.cla() plt.close()
def draw_basemap(ax, extent=None, xticks=None, yticks=None, grid=False): """ Draws a basemap on which to plot data. Map features include continents and country borders. Option to set lat/lon tickmarks and draw gridlines. Parameters ---------- ax : plot Axes on which to draw the basemap extent : float Set map extent to [lonmin, lonmax, latmin, latmax] Default: None (uses global extent) grid : bool Whether to draw grid lines. Default: False xticks : float array of xtick locations (longitude tick marks) yticks : float array of ytick locations (latitude tick marks) Returns ------- ax : plot Axes with Basemap Notes ----- - Grayscale colors can be set using 0 (black) to 1 (white) - Alpha sets transparency (0 is transparent, 1 is solid) Author ------ Tessa Montini, [email protected] """ # Use map projection (CRS) of the given Axes mapcrs = ax.projection ## Map Extent # If no extent is given, use global extent if extent is None: ax.set_global() # If extent is given, set map extent to lat/lon bounding box else: ax.set_extent(extent, crs=mapcrs) # Add map features (continents and country borders) ax.add_feature(cfeature.LAND, facecolor='0.9') ax.add_feature(cfeature.BORDERS, edgecolor='0.4', linewidth=0.8) ax.add_feature(cfeature.COASTLINE, edgecolor='0.4', linewidth=0.8) ## Tickmarks/Labels # Set xticks if requested if xticks is not None: ax.set_xticks(xticks, crs=mapcrs) lon_formatter = LongitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) # Set yticks if requested if yticks is not None: ax.set_yticks(yticks, crs=mapcrs) lat_formatter = LatitudeFormatter() ax.yaxis.set_major_formatter(lat_formatter) # apply tick parameters ax.tick_params(direction='out', labelsize=8.5, length=4, pad=2, color='black') ## Gridlines # Draw gridlines if requested if (grid == True): ax.grid(color='k', alpha=0.5, linewidth=0.5, linestyle='--') return ax
def plot_ppi_map(fig, ax, cx, lon, lat, radar_data, title=None, normvar=None, cmap=None, \ cmap_bins=16, extend=None, projection=ccrs.PlateCarree(), orient="vertical", \ clabel=None, continuously=False): """ 显示带底图的雷达图像 :param fig:matplotlib的fig对象 :param ax: axes对象 :param cx:colorbar axes对象 :param lon: 经度网格 :param lat: 纬度网格 :param radar_data: 雷达数据产品 :param title: 画图的title :param normvar: cmap的最小最大值 :param cmap:cmap的类型 :param cmap_bins: cmap分多少段 :param extend: 图像的lat lon的范围(minlon, maxlon, minlat, maxlat) :param projection: 地图的投影方式 :param orient: colorbar的朝向 :param clabel: colorbar的title :param continuously:使用采用连续的colorbar :return: """ if normvar is None: vmin = -5 vmax = 75 else: vmin, vmax = normvar if extend is None: min_lon = np.min(lon) max_lon = np.max(lon) min_lat = np.min(lat) max_lat = np.max(lat) else: min_lon, max_lon, min_lat, max_lat = extend if title is None: title = "" if clabel is None: clabel = "" if continuously: cmap_bins = 256 cmaps = plt.get_cmap(cmap) levels = MaxNLocator(nbins=cmap_bins).tick_values(vmin, vmax) norm = BoundaryNorm(levels, ncolors=cmaps.N, clip=True) ax.set_global() pm = ax.pcolormesh(lon, lat, radar_data, transform=projection, cmap=cmap, norm=norm, zorder=4) ax.add_feature(cfeature.OCEAN.with_scale('50m'), zorder=0) ax.add_feature(cfeature.NaturalEarthFeature('physical', 'land', '50m',\ edgecolor='none', facecolor="white"), zorder=1) ax.add_feature(cfeature.LAKES.with_scale('50m'), zorder=2) ax.add_feature(cfeature.RIVERS.with_scale('50m'), zorder=3) ax.set_extent([min_lon, max_lon, min_lat, max_lat], projection) ax.add_feature(cfeature.ShapelyFeature(CN_shp_info.geometries(), projection,\ edgecolor='k', facecolor='none'), linewidth=0.5, \ linestyle='-' , zorder=5, alpha=0.8) if continuously: cbar = fig.colorbar(mappable=pm, cax=cx, ax=ax, orientation=orient) else: cbar = fig.colorbar(mappable=pm, cax=cx, ax=ax, orientation=orient, ticks=levels) cbar.set_ticklabels(RadarGraphMap._FixTicks(levels)) cbar.set_label(clabel) ax.set_aspect("equal") ax.set_title(title, fontsize=15) parallels = np.arange(int(min_lat), math.ceil(max_lat) + 1, 1) meridians = np.arange(int(min_lon), math.ceil(max_lon) + 1, 1) ax.set_xticks(meridians, crs=projection) ax.set_yticks(parallels, crs=projection) lon_formatter = LongitudeFormatter() lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter)
def PlotComposites(var_pos, var_neg, lat, lon, title, filename): proj = ccrs.PlateCarree(central_longitude=180) fig = plt.figure(1, (10, 6.7), 300) ax = plt.subplot(2, 1, 1, projection=proj) clevs = np.arange(-60, 70, 10) barra = plt.cm.RdBu_r ax.set_extent([0, 359, -90, 20], crs=ccrs.PlateCarree()) im = ax.contourf(lon, lat, var_pos, clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-60, vmax=60) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) ax.coastlines() ax.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) ax.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax.xaxis.set_major_formatter(lon_formatter) ax.yaxis.set_major_formatter(lat_formatter) plt.title('+NINIO3.4 YEARS') ax1 = plt.subplot(2, 1, 2, projection=proj) barra = plt.cm.RdBu_r ax1.set_extent([0, 359, -90, 20], crs=ccrs.PlateCarree()) im = ax1.contourf(lon, lat, var_neg, clevs, transform=ccrs.PlateCarree(), cmap=barra, extend='both', vmin=-60, vmax=60) barra.set_under(barra(0)) barra.set_over(barra(barra.N - 1)) ax1.coastlines() ax1.add_feature(cartopy.feature.BORDERS, linestyle='-', alpha=.5) #countries ax1.gridlines(crs=proj, linewidth=0.3, linestyle='-') lon_formatter = LongitudeFormatter(zero_direction_label=True) lat_formatter = LatitudeFormatter() ax1.xaxis.set_major_formatter(lon_formatter) ax1.yaxis.set_major_formatter(lat_formatter) plt.title('-NINIO3.4 YEARS') plt.suptitle(title, fontsize=12, x=0.47, y=0.9) fig.subplots_adjust(right=0.8) fig.subplots_adjust(bottom=0.17, top=0.82, hspace=0.2, wspace=0.05) cbar_ax = fig.add_axes([0.33, 0.1, 0.25, 0.05]) fig.colorbar(im, cax=cbar_ax, orientation='horizontal') plt.savefig(filename, dpi=300, bbox_inches='tight', orientation='landscape', papertype='A4') plt.clf() plt.cla() plt.close()
def plot_map(cl=0.0, lat=None, lon=None, profile=None, p_direct=True, geology=False, states=False): """plot a map""" ax = plt.gca() if lat and lon: ax.set_extent((lon[0], lon[1], lat[0], lat[1])) else: ax.set_global() ax.frameon = True ax.outline_patch.set_linewidth(0.75) # Set gridlines. NO LABELS HERE, there is a bug in the gridlines # function around 180deg gl = ax.gridlines(crs=PlateCarree(central_longitude=0.0), draw_labels=False, linewidth=1, color='lightgray', alpha=0.5, linestyle='-', zorder=-1.5) gl.top_labels = False gl.left_labels = False gl.xlines = True # Add Coastline ax.add_feature(cartopy.feature.LAND, zorder=-2, edgecolor='black', linewidth=0.5, facecolor=(0.9, 0.9, 0.9)) # Add the biggest waterbodies ax.add_feature(cartopy.feature.NaturalEarthFeature('physical', 'lakes', '110m'), zorder=-2, edgecolor='black', linewidth=0.5, facecolor='w') # ax.add_feature(cartopy.feature.RIVERS, zorder=-2, edgecolor='black', # linewidth=0.5, facecolor=(0.9, 0.9, 0.9)) if lat and lon: # dy = np.floor((lat[1] - lat[0])/6) dx = np.floor((lat[1] - lat[0]) / 6) xt = np.arange(lon[0], lon[1], dx) yt = np.arange(lat[0], lat[1], dx) else: xt = np.linspace(-180, 180, 13) yt = np.linspace(-90, 90, 13) ax.set_xticks(xt, crs=ccrs.PlateCarree()) ax.set_yticks(yt, crs=ccrs.PlateCarree()) ax.xaxis.set_major_formatter(LongitudeFormatter()) ax.yaxis.set_major_formatter(LatitudeFormatter()) # ax.set_xticks(xt, crs=ccrs.Robinson()) # ax.set_yticks(yt, crs=ccrs.Robinson()) # ax.xaxis.set_major_formatter(LongitudeFormatter()) # ax.yaxis.set_major_formatter(LatitudeFormatter()) if geology: ax.add_wms(wms='https://mrdata.usgs.gov/services/worldgeol?', layers=['geology'], zorder=-2) if states: ax.add_feature(feature=cartopy.feature.STATES, linewidth=0.25, zorder=-2) if profile: if type(profile) == tuple: if p_direct: plt.plot((profile[0], profile[1]), (profile[2], profile[3]), color='blue', linewidth=1.5, transform=PlateCarree(), label='profile 1') else: p = profile ax.add_patch( matplotlib.patches.Rectangle(xy=(p[0], p[2]), height=p[3] - p[2], width=p[1] - p[0], alpha=.2, facecolor='blue')) else: # colorlist if p_direct: for ii, p in enumerate(profile): plt.plot((p[0], p[1]), (p[2], p[3]), linewidth=1.5, transform=PlateCarree(), label='profile ' + str(ii + 1)) else: cl = ['b', 'g', 'r', 'c', 'm', 'y', 'k', 'grey', 'tab:purple'] for ii, p in enumerate(profile): ax.add_patch( matplotlib.patches.Rectangle(xy=(p[0], p[2]), height=p[3] - p[2], width=p[1] - p[0], alpha=.2, label=ii, facecolor=cl[ii])) # ax.legend() return ax
def test_LongitudeFormatter_bad_projection(): formatter = LongitudeFormatter() formatter.axis = Mock(axes=Mock(GeoAxes, projection=ccrs.Orthographic())) message = 'This formatter cannot be used with non-rectangular projections.' with pytest.raises(TypeError, message=message): formatter(0)
def test_LongitudeFormatter_bad_axes(): formatter = LongitudeFormatter() formatter.axis = Mock(axes=Mock(Axes, projection=ccrs.PlateCarree())) message = 'This formatter can only be used with cartopy axes.' with assert_raises_regexp(TypeError, message): formatter(0)