def test_scatter_longitude(self): import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) iplt.scatter(self.lat_lon_cube, self.lat_lon_cube.coord('longitude'), axes=ax) plt.close(fig)
def main(): # Enable a future option, to ensure that the netcdf load works the same way # as in future Iris versions. iris.FUTURE.netcdf_promote = True # Load the gridded temperature and salinity data. fname = iris.sample_data_path('atlantic_profiles.nc') cubes = iris.load(fname) theta, = cubes.extract('sea_water_potential_temperature') salinity, = cubes.extract('sea_water_practical_salinity') # Extract profiles of temperature and salinity from a particular point in # the southern portion of the domain, and limit the depth of the profile # to 1000m. lon_cons = iris.Constraint(longitude=330.5) lat_cons = iris.Constraint(latitude=lambda l: -10 < l < -9) depth_cons = iris.Constraint(depth=lambda d: d <= 1000) theta_1000m = theta.extract(depth_cons & lon_cons & lat_cons) salinity_1000m = salinity.extract(depth_cons & lon_cons & lat_cons) # Plot these profiles on the same set of axes. In each case we call plot # with two arguments, the cube followed by the depth coordinate. Putting # them in this order places the depth coordinate on the y-axis. # The first plot is in the default axes. We'll use the same color for the # curve and its axes/tick labels. plt.figure(figsize=(5, 6)) temperature_color = (.3, .4, .5) ax1 = plt.gca() iplt.plot(theta_1000m, theta_1000m.coord('depth'), linewidth=2, color=temperature_color, alpha=.75) ax1.set_xlabel('Potential Temperature / K', color=temperature_color) ax1.set_ylabel('Depth / m') for ticklabel in ax1.get_xticklabels(): ticklabel.set_color(temperature_color) # To plot salinity in the same axes we use twiny(). We'll use a different # color to identify salinity. salinity_color = (.6, .1, .15) ax2 = plt.gca().twiny() iplt.plot(salinity_1000m, salinity_1000m.coord('depth'), linewidth=2, color=salinity_color, alpha=.75) ax2.set_xlabel('Salinity / PSU', color=salinity_color) for ticklabel in ax2.get_xticklabels(): ticklabel.set_color(salinity_color) plt.tight_layout() iplt.show() # Now plot a T-S diagram using scatter. We'll use all the profiles here, # and each point will be coloured according to its depth. plt.figure(figsize=(6, 6)) depth_values = theta.coord('depth').points for s, t in iris.iterate.izip(salinity, theta, coords='depth'): iplt.scatter(s, t, c=depth_values, marker='+', cmap='RdYlBu_r') ax = plt.gca() ax.set_xlabel('Salinity / PSU') ax.set_ylabel('Potential Temperature / K') cb = plt.colorbar(orientation='horizontal') cb.set_label('Depth / m') plt.tight_layout() iplt.show()
def test_yaxis_labels_with_axes(self): import matplotlib.pyplot as plt fig = plt.figure() ax = fig.add_subplot(111) ax.set_ylim(0, 3) iplt.scatter(self.cube, self.cube.coord('str_coord'), axes=ax) plt.close(fig) self.assertPointsTickLabels('yaxis', ax)
def test_scatter_with_c_kwarg_specified_mappable(self): mappable_initial = scatter(self.traj_lon, self.traj_lat, c=self.traj_lon.points) mappable = scatter(self.traj_lon, self.traj_lat, c=self.traj_lon.points, cmap='cool') cbar = plt.colorbar(mappable_initial) self.assertIs(cbar.mappable, mappable_initial)
def scatter(x, y, *args, **kwargs): """ Draws a labelled scatter plot based on the given cubes or coordinates. See :func:`iris.plot.scatter` for details of valid arguments and keyword arguments. """ result = iplt.scatter(x, y, *args, **kwargs) _label_1d_plot(x, y) return result
def main(): # Load the gridded temperature and salinity data. fname = iris.sample_data_path('atlantic_profiles.nc') cubes = iris.load(fname) theta, = cubes.extract('sea_water_potential_temperature') salinity, = cubes.extract('sea_water_practical_salinity') # Extract profiles of temperature and salinity from a particular point in # the southern portion of the domain, and limit the depth of the profile # to 1000m. lon_cons = iris.Constraint(longitude=330.5) lat_cons = iris.Constraint(latitude=lambda l: -10 < l < -9) depth_cons = iris.Constraint(depth=lambda d: d <= 1000) theta_1000m = theta.extract(depth_cons & lon_cons & lat_cons) salinity_1000m = salinity.extract(depth_cons & lon_cons & lat_cons) # Plot these profiles on the same set of axes. In each case we call plot # with two arguments, the cube followed by the depth coordinate. Putting # them in this order places the depth coordinate on the y-axis. # The first plot is in the default axes. We'll use the same color for the # curve and its axes/tick labels. fig = plt.figure(figsize=(5, 6)) temperature_color = (.3, .4, .5) ax1 = plt.gca() iplt.plot(theta_1000m, theta_1000m.coord('depth'), linewidth=2, color=temperature_color, alpha=.75) ax1.set_xlabel('Potential Temperature / K', color=temperature_color) ax1.set_ylabel('Depth / m') for ticklabel in ax1.get_xticklabels(): ticklabel.set_color(temperature_color) # To plot salinity in the same axes we use twiny(). We'll use a different # color to identify salinity. salinity_color = (.6, .1, .15) ax2 = plt.gca().twiny() iplt.plot(salinity_1000m, salinity_1000m.coord('depth'), linewidth=2, color=salinity_color, alpha=.75) ax2.set_xlabel('Salinity / PSU', color=salinity_color) for ticklabel in ax2.get_xticklabels(): ticklabel.set_color(salinity_color) plt.tight_layout() iplt.show() # Now plot a T-S diagram using scatter. We'll use all the profiles here, # and each point will be coloured according to its depth. plt.figure(figsize=(6, 6)) depth_values = theta.coord('depth').points for s, t in iris.iterate.izip(salinity, theta, coords='depth'): iplt.scatter(s, t, c=depth_values, marker='+', cmap='RdYlBu_r') ax = plt.gca() ax.set_xlabel('Salinity / PSU') ax.set_ylabel('Potential Temperature / K') cb = plt.colorbar(orientation='horizontal') cb.set_label('Depth / m') plt.tight_layout() iplt.show()
def test_yaxis_labels(self): iplt.scatter(self.cube, self.cube.coord('str_coord')) self.assertBoundsTickLabels('yaxis')
def test_scatter_with_c_kwarg(self): mappable = scatter(self.traj_lon, self.traj_lat, c=self.traj_lon.points) cbar = plt.colorbar() self.assertIs(cbar.mappable, mappable)
def main(): # Load the gridded temperature and salinity data. fname = iris.sample_data_path("atlantic_profiles.nc") cubes = iris.load(fname) (theta, ) = cubes.extract("sea_water_potential_temperature") (salinity, ) = cubes.extract("sea_water_practical_salinity") # Extract profiles of temperature and salinity from a particular point in # the southern portion of the domain, and limit the depth of the profile # to 1000m. lon_cons = iris.Constraint(longitude=330.5) lat_cons = iris.Constraint(latitude=lambda l: -10 < l < -9) depth_cons = iris.Constraint(depth=lambda d: d <= 1000) theta_1000m = theta.extract(depth_cons & lon_cons & lat_cons) salinity_1000m = salinity.extract(depth_cons & lon_cons & lat_cons) # Plot these profiles on the same set of axes. Depth is automatically # recognised as a vertical coordinate and placed on the y-axis. # The first plot is in the default axes. We'll use the same color for the # curve and its axes/tick labels. plt.figure(figsize=(5, 6)) temperature_color = (0.3, 0.4, 0.5) ax1 = plt.gca() iplt.plot( theta_1000m, linewidth=2, color=temperature_color, alpha=0.75, ) ax1.set_xlabel("Potential Temperature / K", color=temperature_color) ax1.set_ylabel("Depth / m") for ticklabel in ax1.get_xticklabels(): ticklabel.set_color(temperature_color) # To plot salinity in the same axes we use twiny(). We'll use a different # color to identify salinity. salinity_color = (0.6, 0.1, 0.15) ax2 = plt.gca().twiny() iplt.plot( salinity_1000m, linewidth=2, color=salinity_color, alpha=0.75, ) ax2.set_xlabel("Salinity / PSU", color=salinity_color) for ticklabel in ax2.get_xticklabels(): ticklabel.set_color(salinity_color) plt.tight_layout() iplt.show() # Now plot a T-S diagram using scatter. We'll use all the profiles here, # and each point will be coloured according to its depth. plt.figure(figsize=(6, 6)) depth_values = theta.coord("depth").points for s, t in iris.iterate.izip(salinity, theta, coords="depth"): iplt.scatter(s, t, c=depth_values, marker="+", cmap="RdYlBu_r") ax = plt.gca() ax.set_xlabel("Salinity / PSU") ax.set_ylabel("Potential Temperature / K") cb = plt.colorbar(orientation="horizontal") cb.set_label("Depth / m") plt.tight_layout() iplt.show()
def plot(self): """ Produce trajectory plot. Returns fig object for further plotting if needed. """ if not self.lines: raise ValueError("TrajectoryPlot: no lines have been added") if self.fig is None: if self.rsmc: self.fig = plt.figure(figsize=[12, 6]) ax = plt.subplot2grid( (3, 3), (0, 0), rowspan=2, colspan=2, projection=ccrs.PlateCarree(central_longitude=self.clon)) elif self.annote: self.fig = plt.figure(figsize=[12, 6]) ax = plt.subplot2grid( (3, 3), (0, 0), rowspan=2, colspan=2, projection=ccrs.PlateCarree(central_longitude=self.clon)) else: self.fig = plt.figure(figsize=[7, 9]) ax = plt.subplot2grid( (3, 1), (0, 0), rowspan=2, projection=ccrs.PlateCarree(central_longitude=self.clon)) ax = plt.gca() for line in self.lines: add_settings = {} if 'add_settings' in line: add_settings = line['add_settings'] style = { 'label': line['label'], 'color': line['colour'], 'linestyle': line['linestyle'], 'linewidth': line['linewidth'], 'marker': line['marker'] } style2 = style.copy() style2.update(add_settings) iplt.plot(line['x'], line['y'], **style2) # Add a black square at the trajectory start point iplt.scatter(line['x'][0], line['y'][0], color='k', marker='s') #Add title and axis labels if self.title is not None: ax.set_title(self.title) # Set the extent # Bug in Cartopy Dec'17 - Global extent will not be plotted with # extent[0] = 0, extent[1] = 360 So the longitudinal extents are # deliberately taken in by 0.1 if abs(self.extent[1] - self.extent[0]) > 330: self.extent[0] = -179.9 self.extent[1] = 179.9 ax.set_extent(self.extent, crs=ccrs.PlateCarree()) # Determine extent of plotting region and use this to # select an appropriate mapping zoom if abs(self.extent[1] - self.extent[0]) < 15.0: res = '10m' elif abs(self.extent[1] - self.extent[0]) < 50.0: res = '50m' else: res = '110m' if self.mapping == 'countries' or self.mapping == 'states': countries = cfeature.NaturalEarthFeature( category='cultural', name='admin_0_countries_lakes', scale=res, facecolor='none') if self.mapping == 'states': states = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_shp', scale=res, facecolor='none') if self.mapping == 'coastlines': ax.coastlines(res) elif self.mapping == 'countries': ax.coastlines(res, zorder=3) ax.add_feature(countries, edgecolor='gray', zorder=2, linewidth=0.5) elif self.mapping == 'states': ax.coastlines(res, zorder=3) ax.add_feature(countries, edgecolor='gray', zorder=2, linewidth=1) ax.add_feature(states, edgecolor='lightgray', zorder=2, linewidth=0.5) elif self.mapping == 'wms': # NOTE WMS mapping does not appear to work for extents # greater than 130 degrees in either direction for a # typical 6x6 sized map. For smaller maps, the useable # WMS extents are smaller. # It should also be noted that if the WMS map # crosses 180E/W, if the northern or southern # edge of the map is on the equator, this will # result in the size of page and the placing of # the map on the page being altered. num_layers = np.linspace(0, 40, 41) layers = ['{:.0f}'.format(x) for x in num_layers] ax.add_wms(wms='http://exxdmmsprd01:6080/arcgis/services/DMMS/' + 'Global_NE_HC_Hybrid_Greyscale/MapServer/WMSServer', layers=layers) #Add gridlines if self.gridlines: try: if self.extent[0] < 180 and self.extent[1] > 180: xlocs, xlocs_extend = compute_grid_line_locs(self.extent) ax.gridlines(xlocs=xlocs_extend) gl = ax.gridlines(draw_labels=True, xlocs=xlocs, linewidth=0.001) else: gl = ax.gridlines(draw_labels=True, linewidth=0.8, alpha=0.9, zorder=9) gl.xlabels_top = False gl.ylabels_right = False gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER except: gl = ax.gridlines() # Add information about the release location and time if provided if self.release_info is not None: release_text = 'Release location: {}, {},\n'.format( self.release_info[0], self.release_info[1]) release_text += 'Release time: {}'.format(self.release_info[2]) ax.annotate(release_text, xy=(0.5, 0.34), xycoords=('axes fraction', 'figure fraction'), xytext=(0, 10), textcoords='offset points', size=12, ha='center', va='bottom') # Apply branding if self.mobrand: insert_logo() return self.fig
def plot_layer(self, layer, mapping): """ Method for plotting each individual layer using the information provided in the layer class. :param layer: field layer to plot. :param mapping: map type to use for plot background. """ # First make sure matplotlib knows which figure to draw on: fig = self.fig alpha = 1.0 if mapping in ['grey_os', 'wms', 'jam']: alpha = 0.5 # Quick plot on a linear scale if only a colormap is given if layer.levels is None and layer.colorscale == 'linear': if layer.plottype == 'pcolormesh': fig.cf1 = iplt.pcolormesh(layer.cube, cmap=layer.cmap, alpha=alpha) elif layer.plottype == 'contour': fig.cf1 = iplt.contour(layer.cube, cmap=layer.cmap, alpha=alpha) elif layer.plottype == 'contourf': fig.cf1 = iplt.contourf(layer.cube, cmap=layer.cmap, alpha=alpha) elif layer.plottype == 'contourf_edge': fig.cf1 = iplt.contourf(layer.cube, cmap=layer.cmap, alpha=alpha) iplt.contour(layer.cube, levels=fig.cf1.levels, colors='k') elif layer.plottype == 'scatter_latlon': fig.cf1 = iplt.scatter(layer.cube.coord('longitude'), layer.cube.coord('latitude'), c=np.atleast_1d(layer.cube.data), marker=layer.marker, s=layer.markersize, edgecolors="k", cmap=layer.cmap) else: if layer.levels[0] > np.max(layer.cube.data): # If max data point is less than lowest level don't # plot and don't add a colorbar layer.cbar = False elif layer.plottype == 'pcolormesh': fig.cf1 = iplt.pcolormesh(layer.cube, cmap=layer.cmap, norm=layer.norm, alpha=alpha) elif layer.plottype == 'contour': fig.cf1 = iplt.contour(layer.cube, levels=layer.levels, cmap=layer.cmap, norm=layer.norm, alpha=alpha) elif layer.plottype == 'contourf': fig.cf1 = iplt.contourf(layer.cube, levels=layer.levels, cmap=layer.cmap, norm=layer.norm, alpha=alpha) elif layer.plottype == 'contourf_edge': fig.cf1 = iplt.contourf(layer.cube, levels=layer.levels, cmap=layer.cmap, norm=layer.norm, alpha=alpha) iplt.contour(layer.cube, levels=layer.levels, colors='k') elif layer.plottype == 'scatter_latlon': fig.cf1 = iplt.scatter(layer.cube.coord('longitude'), layer.cube.coord('latitude'), c=np.atleast_1d(layer.cube.data), marker=layer.marker, s=layer.markersize, edgecolors="k", label=layer.label, cmap=layer.cmap, norm=layer.norm) # Set an axes extent (assuming extent is given in WGS84) # Needs to follow plot in order that axes have become geoaxes if self.extent is not None: plt.gca().set_extent(self.extent, crs=ccrs.PlateCarree()) # Add a colorbar if required # First extract or determine required orientation: if layer.cbar_orientation: layer.cbar_orientation = layer.cbar_orientation elif layer.colorscale == 'linear': layer.cbar_orientation = 'horizontal' else: layer.cbar_orientation = 'vertical' # Please note that at this point, unless the 'layer.cbar' variable is # explicitly set as False, a colorbar will be constructed anyway. if layer.cbar is not False: layer.construct_cbar(fig.cf1, position=None, orientation=layer.cbar_orientation, title=None, title_fontsize=None, label_fontsize=None, tickmark_size=None) # Tell the object which fig to hold on to: self.fig = fig
def test_yaxis_labels(self): iplt.scatter(self.cube, self.cube.coord("str_coord")) self.assertBoundsTickLabels("yaxis")
def plot(self, legendcols=None): """ Produce plot. :param legendcols: Number of columns to include in legend. """ if not self.lines: raise ValueError("SoccerPlot: no lines have been added") if self.fig is None: self.fig = plt.figure() ax = self.fig.add_subplot(111) #Scatter Plot for line in self.lines: if line['marker'] is None: line['marker'] = 'o' #Default value for a scatter plot #Check has coordinates if line['cube'].coords(self.stat_xaxis) and \ line['cube'].coords(self.stat_yaxis): #Check that data are not all NaNs: xaxispts = line['cube'].coord(self.stat_xaxis).points yaxispts = line['cube'].coord(self.stat_yaxis).points if not np.isnan(np.nanmax(xaxispts)) and \ not np.isnan(np.nanmax(yaxispts)): iplt.scatter(line['cube'].coord(self.stat_xaxis), line['cube'].coord(self.stat_yaxis), color=np.atleast_1d(line['colour']), label=line['label'], marker=line['marker'], edgecolor='k', s=30) else: raise ValueError( "Cube does not have statistics coordinates \n" + "May need to run get_stats() first") #Set x & y axis limits range_x = self.get_range(self.stat_xaxis) if range_x is not None: ax.set_xlim(range_x) range_y = self.get_range(self.stat_yaxis) if range_y is not None: ax.set_ylim(range_y) #Plot goal regions if self.stat_xgoal is None: #Get goal if not already set self.stat_xgoal = self.get_goals(self.stat_xaxis) if self.stat_ygoal is None: #Get goal if not already set self.stat_ygoal = self.get_goals(self.stat_yaxis) if self.stat_xgoal is not None and self.stat_ygoal is not None: #Can plot goals - plot as a square for xgoal, ygoal in zip(self.stat_xgoal, self.stat_ygoal): xpoints = [xgoal, -xgoal, -xgoal, xgoal, xgoal] ypoints = [ygoal, ygoal, -ygoal, -ygoal, ygoal] ax.plot(xpoints, ypoints, 'k--') #Add lines through zero ax.plot(ax.get_xlim(), [0, 0], 'k') ax.plot([0, 0], ax.get_ylim(), 'k') #Add legend if self.legend: if legendcols is None: plotting_functions.add_legend_belowaxes(scatterpoints=1) else: plotting_functions.add_legend_belowaxes(scatterpoints=1, ncol=legendcols) #Add title if self.title is None: self.gen_title() ax.set_title(self.title) #Add x and y labels if self.xlabel is None: if self.stat_xaxis in timeseries_stats.STATS_INFO: self.xlabel = timeseries_stats.STATS_INFO[ self.stat_xaxis]['long_name'] else: self.xlabel = self.stat_xaxis ax.set_xlabel(self.xlabel) if self.ylabel is None: if self.stat_yaxis in timeseries_stats.STATS_INFO: self.ylabel = timeseries_stats.STATS_INFO[ self.stat_yaxis]['long_name'] else: self.ylabel = self.stat_yaxis ax.set_ylabel(self.ylabel) #Add gridlines if self.gridlines: plt.grid() # Apply branding if self.mobrand: line_plot.add_mobranding() return self.fig
lon_points = [lp + 360 if lp < 0 else lp for lp in lon_points] cube.coord('longitude').points = lon_points clon = 180 # Set up figure fig = plt.figure(figsize=[11, 7]) # Scatter plot the plume showing altitude by colour ax1 = plt.subplot2grid((3, 3), (0, 0), colspan=2, rowspan=2, projection=ccrs.PlateCarree(central_longitude=clon)) cf = iplt.scatter(cube.coord('longitude'), cube.coord('latitude'), s=20, c=cube.coord('height').points, edgecolor='', cmap=cmap, norm=norm) ax1.coastlines('10m') ax1.gridlines() ax1.set_extent(extent) gl = ax1.gridlines(draw_labels=True, linewidth=0.8, alpha=0.9, zorder=9) gl.xlabels_top = False gl.ylabels_right = False gl.xformatter = LONGITUDE_FORMATTER gl.yformatter = LATITUDE_FORMATTER # Scatter plot a cross-section through the plume ax2 = plt.subplot2grid((3, 3), (2, 0), colspan=2)