def hatching(ax, lat, lon, condition, hatch='/////', force=False, wrap_lon=False): """Adds a hatching layer to an axis object. Parameters ---------- ax : matplotlib.pyplot.axis object lat : sequence of float, shape (M,) lon : sequence of float, shape (N,) condition : sequence of bool, shape (M, N) Hatching will be drawn where condition is True. hatch : valid hatch string Note that multiple equivalent characters will lead to a finer hatching. force : bool, optional If True also work with unevenly spaced lat and lon. This might lead to unexpected behavior if the gird is too uneven. wrap_lon : bool, optional Wrap longitude to [-180, 180). Returns ------- None""" if isinstance(lat, xr.core.dataarray.DataArray): lat = lat.data if isinstance(lon, xr.core.dataarray.DataArray): lon = lon.data dlat = np.unique(lat[1:] - lat[:-1]) dlon = np.unique(lon[1:] - lon[:-1]) if force: dlat = [np.mean(dlat)] dlon = [np.mean(dlon)] assert len(dlat) == 1, 'must be evenly spaced' assert len(dlon) == 1, 'must be evenly spaced' dxx = dlon[0] / 2 dyy = dlat[0] / 2 assert np.shape(condition) == (len(lat), len(lon)) ii, jj = np.where(condition) lat_sel = lat[ii] lon_sel = lon[jj] if wrap_lon: lon_sel = [ll if ll < 180 else ll - 360 for ll in lon_sel] patches = [ Polygon([[xx - dxx, yy + dyy], [xx - dxx, yy - dyy], [xx + dxx, yy - dyy], [xx + dxx, yy + dyy]]) for xx, yy in zip(lon_sel, lat_sel) ] pp = PatchCollection(patches) pp.set_alpha(0.) pp.set_hatch(hatch) ax.add_collection(pp)
class PlotConductors(object): # Supported conductor types conductor_types = ['Box'] # Attributes template conductor_attributes = {'xcent': None, 'ycent': None, 'zcent': None, 'xsize': None, 'ysize': None, 'zsize': None, 'voltage': None, 'permeability': None, 'permittivity': None} def __init__(self, plot_axes=None, xbounds=None, zbounds=None): """ Class for plotting of conductors in 2D (XZ). Will plot conductors in simulation domain on an X vs Z plot. Bounds and scaling are automatically determined Args: plot_axes: Optional matplotlib axes object to pass for plotting. Normally the axes object is generated by PlotConductors automatically. xbounds (tuple)(xmin, xmax): Optional Set bounds in x for plotting. Normally determined from Warp values in memory. zbounds (tuple)(zmin, zmax): Optional Set bounds in z for plotting. Normally determined from Warp values in memory. """ try: self.xmin = w3d.xmmin self.xmax = w3d.xmmax self.zmin = w3d.zmmin self.zmax = w3d.zmmax except (NameError, AttributeError): try: self.xmin = xbounds[0] self.xmax = xbounds[1] self.zmin = zbounds[0] self.zmax = zbounds[1] except TypeError: raise TypeError("Must assign xbounds and zbounds") if xbounds: self.xmin = xbounds[0] self.xmax = xbounds[1] if zbounds: self.zmin = zbounds[0] self.zmax = zbounds[1] # Try to guess an ideal scaling if abs(self.xmax - self.xmin) * 1. > 10.: self.scale = 1. elif abs(self.xmax - self.xmin) * 1e3 > 1.: self.scale = 1e3 elif abs(self.xmax - self.xmin) * 1e6 > 1.: self.scale = 1e6 else: self.scale = 1e9 self.fig = None self.plot_axes = plot_axes self.legend_axes = None self.conductors = [] self.voltages = [] self.dielectrics = [] self.permittivities = [] self.conductor_patches = None self.dielectric_patches = None self.conductor_patch_colors = [] self.dielectric_patch_colors = [] self.conductor_legend_handles = [] self.dielectric_legend_handles = [] self.legend_fontsize = 5 self.legend_anchor = (2.25, 1.0) # Color options self.map = plt.cm.seismic self.positive_voltage = self.map(15) self.negative_voltage = self.map(240) self.ground_voltage = 'grey' self.variable_voltage_color = True # If true use color that varies with voltage, else fixed color for +/- def __call__(self, solver): self.solver = solver self.conductor_coordinates(solver) self.create_axes() self.conductor_collection() plt.grid() @run_once def conductor_coordinates(self, solver): """ Runs logic for finding which conductors can be plotted and run appropriate patch creation functions. Args: solver: Warp fieldsolver object containing conductors to be plotted. Returns: None """ # Iterate through all conductor lists in the solver for key in solver.installedconductorlists: # Iterate through all conductor objects for conductor in solver.installedconductorlists[key]: # Perform check to make sure this is a conductor the code knows how to handle for obj_type in self.conductor_types: if isinstance(conductor, getattr(field_solvers.generateconductors, obj_type)): if conductor.permittivity is None: self.conductors.append(self.set_rectangle_patch(conductor)) self.voltages.append(conductor.voltage) if conductor.permittivity is not None: self.dielectrics.append(self.set_rectangle_patch(conductor, dielectric=True)) self.permittivities.append(conductor.permittivity) def conductor_collection(self): # TODO: Once dielectrics register with solver add in loop to append them to dielectric array if not self.plot_axes: self.create_axes() if len(self.voltages) > 0: self.set_collection_colors(self.conductor_patch_colors, self.voltages, self.map) # Assign patches for conductors to the plot axes self.conductor_patches = PatchCollection(self.conductors) self.conductor_patches.set_color(self.conductor_patch_colors) self.plot_axes.add_collection(self.conductor_patches) if len(self.permittivities) > 0: self.set_collection_colors(self.dielectric_patch_colors, self.permittivities, plt.cm.viridis) # Assign patches for dielectrics to the plot axes self.dielectric_patches = PatchCollection(self.dielectrics) self.dielectric_patches.set_color(self.dielectric_patch_colors) self.dielectric_patches.set_hatch('//') self.plot_axes.add_collection(self.dielectric_patches) # Setup the legend and set data for legend axes self.create_legend() if len(self.voltages) > 0: cond_legend = self.legend_axes.legend(handles=self.conductor_legend_handles, bbox_to_anchor=self.legend_anchor, borderaxespad=0., fontsize=self.legend_fontsize, title='Voltage (V)') self.legend_axes.add_artist(cond_legend) if len(self.permittivities) > 0: diel_legend = self.legend_axes.legend(handles=self.dielectric_legend_handles, bbox_to_anchor=(self.legend_anchor[0] + 0.05, self.legend_anchor[1] - 0.2), borderaxespad=0., fontsize=self.legend_fontsize, title=' Relative\nPermittivity') self.legend_axes.add_artist(diel_legend) def set_collection_colors(self, color_collection, color_values, map): # Wanted color scaling to always be red for negative and blue for positive (assuming bl-r colormap) # Created custom linear scaling to using halves of color map for +/- consistently, even if only one sign present if self.variable_voltage_color: # Min/maxes for linear mapping of voltage to colormap negative_min = min(color_values) try: negative_max = max([i for i in color_values if i < 0.]) except ValueError: negative_max = 0. try: positive_min = min([i for i in color_values if i > 0.]) except ValueError: positive_min = 0. positive_max = max(color_values) # Perform mapping for voltage in color_values: if voltage < 0.: try: color = int(-115. / abs(negative_max - negative_min) * voltage - 115. / abs(negative_max - negative_min) * negative_max + 115.) except ZeroDivisionError: color = 240 color_collection.append(map(color)) elif voltage > 0.: try: color = int(-113. / (positive_max - positive_min) * voltage + 113. / (positive_max - positive_min) * positive_max + 2) except ZeroDivisionError: color = 15 color_collection.append(map(color)) elif voltage == 0.: color_collection.append('grey') else: # Just use same color for all + or - voltages for voltage in color_values: if voltage < 0.: color_collection.append(map(240)) elif voltage > 0.: color_collection.append(map(15)) elif voltage == 0.: color_collection.append('grey') def set_rectangle_patch(self, conductor, dielectric=False): """ Creates a mpl.patches.Rectangle object to represent a box in the XZ plane. Args: conductor: Warp conductor object Returns: mpl.patches.Rectangle object """ try: x = conductor.zcent y = conductor.xcent xlength = conductor.zsize ylength = conductor.xsize except: print "Conductor does not have correct attributes to plot: \n{}".format(conductor) return xcorner = x - xlength / 2. ycorner = y - ylength / 2. if dielectric: p = patches.Rectangle( (xcorner * self.scale, ycorner * self.scale), xlength * self.scale, ylength * self.scale) # fill=False, # lw=3, # color='k', # hatch='/') else: p = patches.Rectangle( (xcorner * self.scale, ycorner * self.scale), xlength * self.scale, ylength * self.scale) return p def create_axes(self): """ Sets up the plotting region. Returns: None """ fig = plt.figure(figsize=(12, 5)) gs = GridSpec(1, 2, width_ratios=[20, 1]) ax1 = fig.add_subplot(gs[0, 0]) ax2 = fig.add_subplot(gs[0, 1]) ax1.set_xticks(self.solver.zmesh * 1e9) ax1.set_yticks(self.solver.xmesh * 1e9) ax1.grid() ax2.axis('off') ax1.set_xlim(self.zmin * self.scale, self.zmax * self.scale) ax1.set_ylim(self.xmin * self.scale, self.xmax * self.scale) prefix = '($mm$)' * (self.scale == 1e3) + '($\mu m$)' * (self.scale == 1e6) + \ '($nm$)' * (self.scale == 1e9) + '($m$)' * (self.scale == 1.) ax1.set_xlabel('z ' + prefix) ax1.set_ylabel('x ' + prefix) self.fig = fig self.plot_axes = ax1 self.legend_axes = ax2 @run_once def create_legend(self): voltage_sort = [] permittivity_sort = [] for voltage, color in zip(self.voltages, self.conductor_patch_colors): if voltage not in voltage_sort: legend_artist = patches.Patch(color=color, label=voltage) self.conductor_legend_handles.append(legend_artist) voltage_sort.append(voltage) for permittivity, color in zip(self.permittivities, self.dielectric_patch_colors): if permittivity not in permittivity_sort: legend_artist = patches.Patch(color=color, label=permittivity, hatch='//') self.dielectric_legend_handles.append(legend_artist) permittivity_sort.append(permittivity) self.conductor_legend_handles = [j for (i, j) in sorted(zip(voltage_sort, self.conductor_legend_handles))] self.dielectric_legend_handles = [j for (i, j) in sorted(zip(permittivity_sort, self.dielectric_legend_handles))] def set_legend_properties(self, fontsize=5, anchor=(2.25, 1.0)): """ Adjust legend fontsize and anchor position. Can be used to fit legend into plotting region. Args: fontsize: Fontsize for legend descriptors. Default value: 5. anchor (x, y): Normalized position (0, 1) for legend. Default: (2.25, 1.0) Returns: """ self.legend_fontsize = fontsize self.legend_anchor = anchor
class PlotConductors(object): # Supported conductor types conductor_types = ['Box'] # Attributes template conductor_attributes = { 'xcent': None, 'ycent': None, 'zcent': None, 'xsize': None, 'ysize': None, 'zsize': None, 'voltage': None, 'permeability': None, 'permittivity': None } def __init__(self, plot_axes=None, xbounds=None, zbounds=None): """ Class for plotting of conductors in 2D (XZ). Will plot conductors in simulation domain on an X vs Z plot. Bounds and scaling are automatically determined Args: plot_axes: Optional matplotlib axes object to pass for plotting. Normally the axes object is generated by PlotConductors automatically. xbounds (tuple)(xmin, xmax): Optional Set bounds in x for plotting. Normally determined from Warp values in memory. zbounds (tuple)(zmin, zmax): Optional Set bounds in z for plotting. Normally determined from Warp values in memory. """ try: self.xmin = w3d.xmmin self.xmax = w3d.xmmax self.zmin = w3d.zmmin self.zmax = w3d.zmmax except (NameError, AttributeError): try: self.xmin = xbounds[0] self.xmax = xbounds[1] self.zmin = zbounds[0] self.zmax = zbounds[1] except TypeError: raise TypeError("Must assign xbounds and zbounds") if xbounds: self.xmin = xbounds[0] self.xmax = xbounds[1] if zbounds: self.zmin = zbounds[0] self.zmax = zbounds[1] # Try to guess an ideal scaling if abs(self.xmax - self.xmin) * 1. > 10.: self.scale = 1. elif abs(self.xmax - self.xmin) * 1e3 > 1.: self.scale = 1e3 elif abs(self.xmax - self.xmin) * 1e6 > 1.: self.scale = 1e6 else: self.scale = 1e9 self.fig = None self.plot_axes = plot_axes self.legend_axes = None self.conductors = [] self.voltages = [] self.dielectrics = [] self.permittivities = [] self.conductor_patches = None self.dielectric_patches = None self.conductor_patch_colors = [] self.dielectric_patch_colors = [] self.conductor_legend_handles = [] self.dielectric_legend_handles = [] self.legend_fontsize = 5 self.legend_anchor = (2.25, 1.0) # Color options self.map = plt.cm.seismic self.positive_voltage = self.map(15) self.negative_voltage = self.map(240) self.ground_voltage = 'grey' self.variable_voltage_color = True # If true use color that varies with voltage, else fixed color for +/- def __call__(self, solver): self.solver = solver self.conductor_coordinates(solver) self.create_axes() self.conductor_collection() plt.grid() @run_once def conductor_coordinates(self, solver): """ Runs logic for finding which conductors can be plotted and run appropriate patch creation functions. Args: solver: Warp fieldsolver object containing conductors to be plotted. Returns: None """ # Iterate through all conductor lists in the solver for key in solver.installedconductorlists: # Iterate through all conductor objects for conductor in solver.installedconductorlists[key]: # Perform check to make sure this is a conductor the code knows how to handle for obj_type in self.conductor_types: if isinstance( conductor, getattr(field_solvers.generateconductors, obj_type)): if conductor.permittivity is None: self.conductors.append( self.set_rectangle_patch(conductor)) self.voltages.append(conductor.voltage) if conductor.permittivity is not None: self.dielectrics.append( self.set_rectangle_patch(conductor, dielectric=True)) self.permittivities.append(conductor.permittivity) def conductor_collection(self): # TODO: Once dielectrics register with solver add in loop to append them to dielectric array if not self.plot_axes: self.create_axes() if len(self.voltages) > 0: self.set_collection_colors(self.conductor_patch_colors, self.voltages, self.map) # Assign patches for conductors to the plot axes self.conductor_patches = PatchCollection(self.conductors) self.conductor_patches.set_color(self.conductor_patch_colors) self.plot_axes.add_collection(self.conductor_patches) if len(self.permittivities) > 0: self.set_collection_colors(self.dielectric_patch_colors, self.permittivities, plt.cm.viridis) # Assign patches for dielectrics to the plot axes self.dielectric_patches = PatchCollection(self.dielectrics) self.dielectric_patches.set_color(self.dielectric_patch_colors) self.dielectric_patches.set_hatch('//') self.plot_axes.add_collection(self.dielectric_patches) # Setup the legend and set data for legend axes self.create_legend() if len(self.voltages) > 0: cond_legend = self.legend_axes.legend( handles=self.conductor_legend_handles, bbox_to_anchor=self.legend_anchor, borderaxespad=0., fontsize=self.legend_fontsize, title='Voltage (V)') self.legend_axes.add_artist(cond_legend) if len(self.permittivities) > 0: diel_legend = self.legend_axes.legend( handles=self.dielectric_legend_handles, bbox_to_anchor=(self.legend_anchor[0] + 0.05, self.legend_anchor[1] - 0.2), borderaxespad=0., fontsize=self.legend_fontsize, title=' Relative\nPermittivity') self.legend_axes.add_artist(diel_legend) def set_collection_colors(self, color_collection, color_values, map): # Wanted color scaling to always be red for negative and blue for positive (assuming bl-r colormap) # Created custom linear scaling to using halves of color map for +/- consistently, even if only one sign present if self.variable_voltage_color: # Min/maxes for linear mapping of voltage to colormap negative_min = min(color_values) try: negative_max = max([i for i in color_values if i < 0.]) except ValueError: negative_max = 0. try: positive_min = min([i for i in color_values if i > 0.]) except ValueError: positive_min = 0. positive_max = max(color_values) # Perform mapping for voltage in color_values: if voltage < 0.: try: color = int(-115. / abs(negative_max - negative_min) * voltage - 115. / abs(negative_max - negative_min) * negative_max + 115.) except ZeroDivisionError: color = 240 color_collection.append(map(color)) elif voltage > 0.: try: color = int(-113. / (positive_max - positive_min) * voltage + 113. / (positive_max - positive_min) * positive_max + 2) except ZeroDivisionError: color = 15 color_collection.append(map(color)) elif voltage == 0.: color_collection.append('grey') else: # Just use same color for all + or - voltages for voltage in color_values: if voltage < 0.: color_collection.append(map(240)) elif voltage > 0.: color_collection.append(map(15)) elif voltage == 0.: color_collection.append('grey') def set_rectangle_patch(self, conductor, dielectric=False): """ Creates a mpl.patches.Rectangle object to represent a box in the XZ plane. Args: conductor: Warp conductor object Returns: mpl.patches.Rectangle object """ try: x = conductor.zcent y = conductor.xcent xlength = conductor.zsize ylength = conductor.xsize except: print "Conductor does not have correct attributes to plot: \n{}".format( conductor) return xcorner = x - xlength / 2. ycorner = y - ylength / 2. if dielectric: p = patches.Rectangle((xcorner * self.scale, ycorner * self.scale), xlength * self.scale, ylength * self.scale) # fill=False, # lw=3, # color='k', # hatch='/') else: p = patches.Rectangle((xcorner * self.scale, ycorner * self.scale), xlength * self.scale, ylength * self.scale) return p def create_axes(self): """ Sets up the plotting region. Returns: None """ fig = plt.figure(figsize=(12, 5)) gs = GridSpec(1, 2, width_ratios=[20, 1]) ax1 = fig.add_subplot(gs[0, 0]) ax2 = fig.add_subplot(gs[0, 1]) ax1.set_xticks(self.solver.zmesh * 1e9) ax1.set_yticks(self.solver.xmesh * 1e9) ax1.grid() ax2.axis('off') ax1.set_xlim(self.zmin * self.scale, self.zmax * self.scale) ax1.set_ylim(self.xmin * self.scale, self.xmax * self.scale) prefix = '($mm$)' * (self.scale == 1e3) + '($\mu m$)' * (self.scale == 1e6) + \ '($nm$)' * (self.scale == 1e9) + '($m$)' * (self.scale == 1.) ax1.set_xlabel('z ' + prefix) ax1.set_ylabel('x ' + prefix) self.fig = fig self.plot_axes = ax1 self.legend_axes = ax2 @run_once def create_legend(self): voltage_sort = [] permittivity_sort = [] for voltage, color in zip(self.voltages, self.conductor_patch_colors): if voltage not in voltage_sort: legend_artist = patches.Patch(color=color, label=voltage) self.conductor_legend_handles.append(legend_artist) voltage_sort.append(voltage) for permittivity, color in zip(self.permittivities, self.dielectric_patch_colors): if permittivity not in permittivity_sort: legend_artist = patches.Patch(color=color, label=permittivity, hatch='//') self.dielectric_legend_handles.append(legend_artist) permittivity_sort.append(permittivity) self.conductor_legend_handles = [ j for (i, j) in sorted(zip(voltage_sort, self.conductor_legend_handles)) ] self.dielectric_legend_handles = [ j for (i, j) in sorted( zip(permittivity_sort, self.dielectric_legend_handles)) ] def set_legend_properties(self, fontsize=5, anchor=(2.25, 1.0)): """ Adjust legend fontsize and anchor position. Can be used to fit legend into plotting region. Args: fontsize: Fontsize for legend descriptors. Default value: 5. anchor (x, y): Normalized position (0, 1) for legend. Default: (2.25, 1.0) Returns: """ self.legend_fontsize = fontsize self.legend_anchor = anchor
def plot_shapefile(f, options='counties', more_options=None, cm='blues', df=None, probas_dict=None, local=False, true_idx=None, show=False, save=False): ''' INPUT: (1) string: shapefile to use (2) string: options to specify that build a nice plot 'counties' or 'rocktypes' or 'geologic_history' 'counties' will plot the counties of just CO, even though this shapefile includes some counties in neighboring states 'rocktypes' will plot all distinct rocktypes in CO 'geologic_history' plots the rocktypes by age rather than unique type (4 age ranges rather than 29 primary rocktypes) (3) string: more options that specify for counties what colors to plot 'by_img_color' or 'by_probability' 'by_img_color' will plot the avg color of each img 'by_probability' will plot scale the colormap to reflect the probability that a given image is (4) string: colormap to specify 'blues' or 'continuous' 'blues' is easy on the eyes for random assignment 'continuous' is good for probabilities (5) Pandas DataFrame: referenced for plotting purposes with some options (6) dictionary: counties as keys, probabilities associated with that county being the true county according to the CNN as values (7) boolean: local photos or not? used for lazy purposes when showing iPhone photos (8) integer: the index in the dataframe of the true county (9) boolean: show the plot? (10) boolean: save the plot? OUPUT: (1) The plotted shapefile, saved or to screen as specified ''' fig = plt.figure(figsize=(20, 10)) ax = fig.add_subplot(111, axisbg='w', frame_on=False) m = Basemap(width=800000, height=550000, resolution='l', projection='aea', lat_1=37., lat_2=41, lon_0=-105.55, lat_0=39) m.readshapefile(f, name='state', color='none') # OPTIONS # if options == 'rocktypes': rocks = np.unique( [shape_info['ROCKTYPE1'] for shape_info in m.state_info]) num_colors = len(rocks) elif options == 'geologic_history': geologic_time_dictionary = load_geologic_history() ranges = [0, 5, 20, 250, 3000] # in Myr all_ranges = [] for r, r_plus1 in zip(ranges[:-1], ranges[1:]): all_ranges += [str(r) + '-' + str(r_plus1)] num_colors = len(all_ranges) elif more_options == 'by_probability': max_proba = max(probas_dict.values()) num_colors = 101 proba_range = np.linspace(0.0, max_proba, num_colors) # COLOR MAPS # if cm == 'blues': cmap = plt.get_cmap('Blues') elif cm == 'continuous': cmap = make_cmyk_greyscale_continuous_cmap() else: cmap = plt.get_cmap(cm) discrete_colormap = [cmap(1. * i / num_colors) for i in range(num_colors)] # LOOP THROUGH SHAPEFILES # for info, shape in zip(m.state_info, m.state): patches = [Polygon(np.array(shape), True)] pc = PatchCollection(patches, edgecolor='k', hatch=None, linewidths=0.5, zorder=2) # OPTIONS OF HOW TO PLOT THE SHAPEFILE # if options == 'counties': county_name = info['COUNTY_NAM'] state_name = info['STATE_NAME'] if state_name != 'Colorado': continue # ignore shapefiles from out of CO # MORE OPTIONS FOR COUNTIES # if more_options == 'by_img_color': locs = np.where(df['county'] == county_name)[0] r_avg = df['avg_r_low'][locs].mean() g_avg = df['avg_g_low'][locs].mean() b_avg = df['avg_b_low'][locs].mean() pc.set_color((r_avg / 255., g_avg / 255., b_avg / 255.)) elif more_options == 'by_probability': proba = probas_dict[county_name] proba_idx = int(proba / max_proba * 100) pc.set_color(discrete_colormap[proba_idx]) pc.set_edgecolor('k') if local: if county_name == 'Denver': pc.set_hatch('//') pc.set_edgecolor('w') if county_name == df['county'][true_idx] and not local: if proba_idx > 60: pc.set_hatch('//') pc.set_edgecolor('w') else: pc.set_hatch('//') pc.set_edgecolor('k') else: pc.set_color(random.choice(discrete_colormap)) elif options == 'rocktypes': rocktype = info['ROCKTYPE1'] idx = np.where(rocks == rocktype)[0][0] pc.set_color(discrete_colormap[idx]) elif options == 'geologic_history': rock_age = info['UNIT_AGE'] for index, (r, r_plus1) in enumerate(zip(ranges[:-1], ranges[1:])): try: if ((geologic_time_dictionary[rock_age] > r) & (geologic_time_dictionary[rock_age] < r_plus1)): idx = index except: idx = 2 # 20-250 was a good middleground for nans pc.set_color(discrete_colormap[idx]) elif options == 'nofill': pc.set_facecolor('none') else: pc.set_color(random.choice(discrete_colormap)) if more_options == 'by_probability': ax2 = fig.add_axes([0.78, 0.1, 0.03, 0.8]) cb = matplotlib.colorbar.ColorbarBase(ax2, cmap=cmap, ticks=proba_range, boundaries=proba_range, format='%1i') labels = [ str(round(proba, 4)) if idx % 10 == 0 else '' for idx, proba in enumerate(proba_range) ] cb.ax.set_yticklabels(labels) cb.ax.set_ylabel('Probability') ax.add_collection(pc) NESW = ['N', 'E', 'S', 'W'] if local: # limited flexibility here for displaying iPhone photos on the side filenums = [5919, 5918, 5917, 5920] filenames = [ '''/Users/jliemansifry/Desktop/outside_galvanize_test/ IMG_{} (1).jpg'''.format(num) for num in filenums ] else: filenames = [ df['base_filename'][true_idx] + cardinal_dir + '.png' for cardinal_dir in NESW ] if more_options == 'by_probability': def add_image(filename, y, label): ax_to_add = fig.add_axes([0., y, .32, .20]) ax_to_add.imshow(imread(filename)) ax_to_add.set_xticks([]) ax_to_add.set_yticks([]) ax_to_add.set_ylabel(label) ys = [0.7, 0.5, 0.3, 0.1] labels = ['North', 'East', 'South', 'West'] for filename, y, label in zip(filenames, ys, labels): add_image(filename, y, label) if save: if local: plt.savefig('model_testing/county_model_v1.2_' + 'Denver.png', dpi=150) else: true_county = df['county'][true_idx] plt.savefig( '''model_testing/county_model_v1.3_newtruecolors_{}_idx_{}.png''' .format(true_county, true_idx), dpi=150) if show: plt.show()