def plot(self): """ plot residual phase tensor """ #get residual phase tensor for plotting self._compute_residual_pt() #filter data if desired if self.med_filt_kernel is not None: self._apply_median_filter(kernel=self.med_filt_kernel) #set position properties for the plot plt.rcParams['font.size'] = self.font_size plt.rcParams['figure.subplot.left'] = self.subplot_left plt.rcParams['figure.subplot.right'] = self.subplot_right plt.rcParams['figure.subplot.bottom'] = self.subplot_bottom plt.rcParams['figure.subplot.top'] = self.subplot_top plt.rcParams['figure.subplot.wspace'] = self.subplot_wspace plt.rcParams['figure.subplot.hspace'] = self.subplot_hspace #make figure instance self.fig = plt.figure(self.fig_num, self.fig_size, dpi=self.fig_dpi) #create axis instance, be sure to make aspect equal or ellipses will #look funny. self.ax = self.fig.add_subplot(1, 1, 1, aspect='equal') #set local parameters with shorter names es = self.ellipse_size ck = self.ellipse_colorby cmap = self.ellipse_cmap ckmin = float(self.ellipse_range[0]) ckmax = float(self.ellipse_range[1]) try: ckstep = float(self.ellipse_range[2]) except IndexError: ckstep = 3 #set the number of segments in case a segmented map is desired nseg = float((ckmax - ckmin) / (2 * ckstep)) if cmap == 'mt_seg_bl2wh2rd': bounds = np.arange(ckmin, ckmax + ckstep, ckstep) #get largest ellipse emax = self.ellipse_scale #emax = self.rpt_array['phimax'].max() #plot phase tensor ellipses for ii, rpt in enumerate(self.rpt_array): phimax = rpt['phimax'] phimin = rpt['phimin'] azimuth = rpt['azimuth'] #get the properties to color the ellipses by try: color_array = rpt[self.ellipse_colorby] except ValueError: raise NameError('{0} is not supported'.format( self.ellipse_colorby)) for jj, ff in enumerate(self.freq_list): if phimin[jj] == 0.0 or phimax[jj] == 0.0: pass else: #make sure the ellipses will be visable eheight = phimin[jj] / emax * es ewidth = phimax[jj] / emax * es #create an ellipse scaled by phimin and phimax and orient #the ellipse so that north is up and east is right #need to add 90 to do so instead of subtracting if self.rot90 == True: ellipd = patches.Ellipse( (rpt['offset'] * self.xstretch, np.log10(ff) * self.ystretch), width=ewidth, height=eheight, angle=azimuth[jj] - 90) else: ellipd = patches.Ellipse( (rpt['offset'] * self.xstretch, np.log10(ff) * self.ystretch), width=ewidth, height=eheight, angle=azimuth[jj]) #get ellipse color if cmap.find('seg') > 0: ellipd.set_facecolor( mtcl.get_plot_color(color_array[jj], self.ellipse_colorby, cmap, ckmin, ckmax, bounds=bounds)) else: ellipd.set_facecolor( mtcl.get_plot_color(color_array[jj], self.ellipse_colorby, cmap, ckmin, ckmax)) # == =add the ellipse to the plot == ======== self.ax.add_artist(ellipd) #--> Set plot parameters #need to sort the offsets and station labels so they plot correctly sdtype = [('offset', np.float), ('station', '|S10')] slist = np.array([(oo, ss) for oo, ss in zip( self.rpt_array['offset'], self.rpt_array['station'])], dtype=sdtype) offset_sort = np.sort(slist, order='offset') self.offset_list = offset_sort['offset'] self.station_list = offset_sort['station'] #min and max frequency of the plot pmin = int(np.floor(np.log10(self.freq_list.min()))) pmax = int(np.ceil(np.log10(self.freq_list.max()))) #set y-axis major ticks to be on each power of 10 self.ax.yaxis.set_ticks( np.arange(pmin * self.ystretch, (pmax + 1) * self.ystretch, self.ystretch)) #set y-ticklabels to coincide with the desired label if self.tscale == 'period': #make tick labels that will represent period yticklabels = [ mtpl.labeldict[-ii] for ii in range(pmin, pmax + 1, 1) ] self.ax.set_ylabel('Period (s)', fontsize=self.font_size + 2, fontweight='bold') elif self.tscale == 'frequency': yticklabels = [ mtpl.labeldict[ii] for ii in range(pmin, pmax + 1, 1) ] self.ax.set_ylabel('Frequency (Hz)', fontsize=self.font_size + 2, fontweight='bold') #--> set y-limits if self.ylimits == None: self.ax.set_ylim(pmin * self.ystretch, pmax * self.ystretch) else: pmin = np.log10(self.ylimits[0]) * self.ystretch pmax = np.log10(self.ylimits[1]) * self.ystretch self.ax.set_ylim(pmin, pmax) #--> set y-axis tick labels self.ax.set_yticklabels(yticklabels) #--> set x-axis label self.ax.set_xlabel('Station', fontsize=self.font_size + 2, fontweight='bold') #set x-axis ticks self.ax.set_xticks(self.offset_list * self.xstretch) #set x-axis tick labels as station names xticklabels = self.station_list if self.xstep != 1: xticklabels = np.zeros(len(self.station_list), dtype=self.station_list.dtype) for xx in range(0, len(self.station_list), self.xstep): xticklabels[xx] = self.station_list[xx] self.ax.set_xticklabels(xticklabels) #--> set x-limits if self.xlimits == None: self.ax.set_xlim(self.offset_list.min() * self.xstretch - es * 2, self.offset_list.max() * self.xstretch + es * 2) else: self.ax.set_xlim(self.xlimits) #--> set title of the plot if self.plot_title == None: pass else: self.ax.set_title(self.plot_title, fontsize=self.font_size + 2) #put a grid on the plot self.ax.grid(alpha=.25, which='both', color=(.25, .25, .25)) #==> make a colorbar with appropriate colors if self.cb_position == None: self.ax2, kw = mcb.make_axes(self.ax, orientation=self.cb_orientation, shrink=.35) else: self.ax2 = self.fig.add_axes(self.cb_position) if cmap == 'mt_seg_bl2wh2rd': #make a color list self.clist = [(cc, cc, 1) for cc in np.arange(0, 1+1./(nseg), 1./(nseg))]+\ [(1, cc, cc) for cc in np.arange(1, -1./(nseg), -1./(nseg))] #make segmented colormap mt_seg_bl2wh2rd = colors.ListedColormap(self.clist) #make bounds so that the middle is white bounds = np.arange(ckmin - ckstep, ckmax + 2 * ckstep, ckstep) #normalize the colors norms = colors.BoundaryNorm(bounds, mt_seg_bl2wh2rd.N) #make the colorbar self.cb = mcb.ColorbarBase(self.ax2, cmap=mt_seg_bl2wh2rd, norm=norms, orientation=self.cb_orientation, ticks=bounds[1:-1]) else: self.cb = mcb.ColorbarBase(self.ax2, cmap=mtcl.cmapdict[cmap], norm=colors.Normalize(vmin=ckmin, vmax=ckmax), orientation=self.cb_orientation) #label the color bar accordingly self.cb.set_label(mtpl.ckdict[ck], fontdict={ 'size': self.font_size, 'weight': 'bold' }) #place the label in the correct location if self.cb_orientation == 'horizontal': self.cb.ax.xaxis.set_label_position('top') self.cb.ax.xaxis.set_label_coords(.5, 1.3) elif self.cb_orientation == 'vertical': self.cb.ax.yaxis.set_label_position('right') self.cb.ax.yaxis.set_label_coords(1.5, .5) self.cb.ax.yaxis.tick_left() self.cb.ax.tick_params(axis='y', direction='in') plt.show()
def plot(self): """ plots the phase tensor elements """ #Set plot parameters plt.rcParams['font.size'] = self.font_size plt.rcParams['figure.subplot.left'] = .1 plt.rcParams['figure.subplot.right'] = .98 plt.rcParams['figure.subplot.bottom'] = .1 plt.rcParams['figure.subplot.top'] = .95 plt.rcParams['figure.subplot.wspace'] = .21 plt.rcParams['figure.subplot.hspace'] = .5 font_dict = {'size':self.font_size, 'weight':'bold'} font_dictt = {'size':self.font_size+2, 'weight':'bold'} #--> create plot instance self.fig = plt.figure(self.fig_num, self.fig_size, dpi=self.fig_dpi) plt.clf() #get phase tensor instance try: self.pt self.pt.rotate(self.rot_z) except AttributeError: self.pt = self._mt.get_PhaseTensor() self.pt.rotate(self.rot_z) self.zinv = self._mt.get_Zinvariants() self.zinv.rotate(self.rot_z) cmap = self.ellipse_cmap ckmin = self.ellipse_range[0] ckmax = self.ellipse_range[1] try: ckstep = float(self.ellipse_range[2]) except IndexError: ckstep = 3 if cmap == 'mt_seg_bl2wh2rd': bounds = np.arange(ckmin, ckmax+ckstep, ckstep) nseg = float((ckmax-ckmin)/(2*ckstep)) #get the properties to color the ellipses by if self.ellipse_colorby == 'phiminang' or \ self.ellipse_colorby == 'phimin': colorarray = self.pt.phimin[0] elif self.ellipse_colorby == 'phidet': colorarray = np.sqrt(abs(self.pt.det[0]))*(180/np.pi) elif self.ellipse_colorby == 'skew' or\ self.ellipse_colorby == 'skew_seg': colorarray = self.pt.beta[0] elif self.ellipse_colorby == 'ellipticity': colorarray = self.pt.ellipticity[0] else: raise NameError(self.ellipse_colorby+' is not supported') #-------------plotPhaseTensor----------------------------------- self.ax1 = self.fig.add_subplot(3, 1, 1, aspect='equal') for ii, ff in enumerate(self._mt.period): #make sure the ellipses will be visable eheight = self.pt.phimin[0][ii]/self.pt.phimax[0][ii]*\ self.ellipse_size ewidth = self.pt.phimax[0][ii]/self.pt.phimax[0][ii]*\ self.ellipse_size #create an ellipse scaled by phimin and phimax and oriented along #the azimuth which is calculated as clockwise but needs to #be plotted counter-clockwise hence the negative sign. ellipd = patches.Ellipse((np.log10(ff)*self.ellipse_spacing, 0), width=ewidth, height=eheight, angle=90-self.pt.azimuth[0][ii]) self.ax1.add_patch(ellipd) #get ellipse color if cmap.find('seg') > 0: ellipd.set_facecolor(mtcl.get_plot_color(colorarray[ii], self.ellipse_colorby, cmap, ckmin, ckmax, bounds=bounds)) else: ellipd.set_facecolor(mtcl.get_plot_color(colorarray[ii], self.ellipse_colorby, cmap, ckmin, ckmax)) #----set axes properties----------------------------------------------- #--> set tick labels and limits xlimits = (np.floor(np.log10(self._mt.period[0])), np.ceil(np.log10(self._mt.period[-1]))) self.ax1.set_xlim(xlimits) tklabels = [] xticks = [] for tk in self.ax1.get_xticks(): try: tklabels.append(mtpl.labeldict[tk]) xticks.append(tk) except KeyError: pass self.ax1.set_xticks(xticks) self.ax1.set_xticklabels(tklabels, fontdict={'size':self.font_size}) self.ax1.set_xlabel('Period (s)', fontdict=font_dict) self.ax1.set_ylim(ymin=-1.5*self.ellipse_size, ymax=1.5*self.ellipse_size) self.ax1.grid(True, alpha=.25, which='major', color=(.25,.25,.25), lw=.25) plt.setp(self.ax1.get_yticklabels(), visible=False) #add colorbar for PT self.cbax = self.fig.add_axes(self.cb_position) if cmap == 'mt_seg_bl2wh2rd': #make a color list clst = [(cc, cc, 1) for cc in np.arange(0,1+1./(nseg),1./(nseg))]+\ [(1, cc, cc) for cc in np.arange(1,-1./(nseg),-1./(nseg))] #make segmented colormap mt_seg_bl2wh2rd = colors.ListedColormap(clst) #make bounds so that the middle is white bounds = np.arange(ckmin-ckstep, ckmax+2*ckstep, ckstep) #normalize the colors norms = colors.BoundaryNorm(bounds, mt_seg_bl2wh2rd.N) #make the colorbar self.cbpt = mcb.ColorbarBase(self.cbax, cmap=mt_seg_bl2wh2rd, norm=norms, orientation='vertical', ticks=bounds[1:-1]) else: self.cbpt = mcb.ColorbarBase(self.cbax, cmap=mtcl.cmapdict[cmap], norm=colors.Normalize(vmin=ckmin, vmax=ckmax), orientation='vertical') self.cbpt.set_ticks([ckmin, ckmax]) self.cbpt.set_ticklabels(['{0:.0f}'.format(ckmin), '{0:.0f}'.format(ckmax)]) self.cbpt.ax.yaxis.set_label_position('left') self.cbpt.ax.yaxis.set_label_coords(-1.05, .5) self.cbpt.ax.yaxis.tick_right() self.cbpt.ax.tick_params(axis='y', direction='in') self.cbpt.set_label(mtpl.ckdict[self.ellipse_colorby], fontdict={'size':self.font_size, 'weight':'bold'}) #---------------plotStrikeAngle----------------------------------- self.ax2 = self.fig.add_subplot(3, 2, 3) az = self.pt.azimuth[0] azerr = self.pt.azimuth[1] #put the strike into a coordinate system that goes from -90 to 90 az[np.where(az > 90)] -= 180 az[np.where(az < -90)] += 180 stlst = [] stlabel = [] #plot phase tensor strike ps2 = self.ax2.errorbar(self._mt.period, az, marker=self.strike_pt_marker, ms=self.marker_size, mfc=self.strike_pt_color, mec=self.strike_pt_color, mew=self.marker_lw, ls='none', yerr=azerr, ecolor=self.strike_pt_color, capsize=self.marker_size, elinewidth=self.marker_lw) stlst.append(ps2[0]) stlabel.append('PT') try: strike = self.zinv.strike strikeerr = np.nan_to_num(self.zinv.strike_err) #put the strike into a coordinate system that goes from -90 to 90 strike[np.where(strike>90)] = strike[np.where(strike>90)]-180 strike[np.where(strike<-90)] = strike[np.where(strike<-90)]+180 #plot invariant strike erxy = self.ax2.errorbar(self._mt.period, strike, marker=self.strike_inv_marker, ms=self.marker_size, mfc=self.strike_inv_color, mec=self.strike_inv_color, mew=self.marker_lw, ls='none', yerr=strikeerr, ecolor=self.strike_inv_color, capsize=self.marker_size, elinewidth=self.marker_lw) stlst.append(erxy[0]) stlabel.append('Z_inv') except AttributeError: print 'Could not get z_invariants from pt, input z if desired.' if self._mt.tipper is not None: #strike from tipper tp = self._mt.get_Tipper() s3 = tp.ang_real+90 #fold to go from -90 to 90 s3[np.where(s3>90)] = s3[np.where(s3>90)]-180 s3[np.where(s3<-90)] = s3[np.where(s3<-90)]+180 #plot strike with error bars ps3 = self.ax2.errorbar(self._mt.period, s3, marker=self.strike_tp_marker, ms=self.marker_size, mfc=self.strike_tp_color, mec=self.strike_tp_color, mew=self.marker_lw, ls='none', yerr=np.zeros_like(s3), ecolor=self.strike_tp_color, capsize=self.marker_size, elinewidth=self.marker_lw) stlst.append(ps3[0]) stlabel.append('Tipper') self.ax2.legend(stlst, stlabel, loc='lower left', markerscale=.5*self.marker_size, borderaxespad=.01, labelspacing=.1, handletextpad=.2, ncol=len(stlst), borderpad=.1, columnspacing=.1) leg = plt.gca().get_legend() ltext = leg.get_texts() # all the text.Text instance in the legend plt.setp(ltext, fontsize=6) # the legend text fontsize if self.strike_limits == None: self.strike_limits = (-89.99, 89.99) self.ax2.set_yscale('linear') self.ax2.set_xscale('log') self.ax2.set_xlim(xmax=10**xlimits[-1], xmin=10**xlimits[0]) self.ax2.set_ylim(self.strike_limits) self.ax2.yaxis.set_major_locator(MultipleLocator(20)) self.ax2.yaxis.set_minor_locator(MultipleLocator(5)) self.ax2.grid(True, alpha=.25, which='both', color=(.25, .25, .25), lw=.25) self.ax2.set_ylabel('Angle (deg)', fontdict=font_dict) self.ax2.set_title('Strike', fontdict=font_dictt) #---------plot Min & Max Phase----------------------------------------- minphi = self.pt.phimin[0] minphierr = self.pt.phimin[1] maxphi = self.pt.phimax[0] maxphierr = self.pt.phimax[1] self.ax3 = self.fig.add_subplot(3, 2, 4, sharex=self.ax2) ermin = self.ax3.errorbar(self._mt.period, minphi, marker=self.ptmin_marker, ms=self.marker_size, mfc='None', mec=self.ptmin_color, mew=self.marker_lw, ls='None', yerr=minphierr, ecolor=self.ptmin_color, capsize=self.marker_size, elinewidth=self.marker_lw) ermax = self.ax3.errorbar(self._mt.period, maxphi, marker=self.ptmax_marker, ms=self.marker_size, mfc='None', mec=self.ptmax_color, mew=self.marker_lw, ls='None', yerr=maxphierr, ecolor=self.ptmax_color, capsize=self.marker_size, elinewidth=self.marker_lw) if self.pt_limits == None: self.pt_limits = [min([self.pt.phimax[0].min(), self.pt.phimin[0].min()])-3, max([self.pt.phimax[0].max(), self.pt.phimin[0].max()])+3] if self.pt_limits[0] < -10: self.pt_limits[0] = -9.9 if self.pt_limits[1] > 100: self.pt_limits[1] = 99.99 self.ax3.set_xscale('log') self.ax3.set_yscale('linear') self.ax3.legend((ermin[0], ermax[0]), ('$\phi_{min}$','$\phi_{max}$'), loc='lower left', markerscale=.5*self.marker_size, borderaxespad=.01, labelspacing=.1, handletextpad=.2, ncol=2, borderpad=.01, columnspacing=.01) leg = plt.gca().get_legend() ltext = leg.get_texts() # all the text.Text instance in the legend plt.setp(ltext, fontsize=6.5) # the legend text fontsize self.ax3.set_ylim(self.pt_limits) self.ax3.grid(True, alpha=.25, which='both', color=(.25, .25, .25), lw=.25) self.ax3.set_ylabel('Phase (deg)', fontdict=font_dict) self.ax3.set_title('$\mathbf{\phi_{min}}$ and $\mathbf{\phi_{max}}$', fontdict=font_dictt) #-----------------------plotSkew--------------------------------------- skew = self.pt.beta[0] skewerr = self.pt.beta[1] self.ax4 = self.fig.add_subplot(3, 2, 5, sharex=self.ax2) erskew = self.ax4.errorbar(self._mt.period, skew, marker=self.skew_marker, ms=self.marker_size, mfc='None', mec=self.skew_color, mew=self.marker_lw, ls='None', yerr=skewerr, ecolor=self.skew_color, capsize=self.marker_size, elinewidth=self.marker_lw) #plot lines indicating not 3d self.ax4.plot([10**xlimits[0], 10**xlimits[-1]], [self.skew_cutoff, self.skew_cutoff], ls='--', color=self.skew_color, lw=1) self.ax4.plot([10**xlimits[0], 10**xlimits[-1]], [-self.skew_cutoff, -self.skew_cutoff], ls='--', color=self.skew_color, lw=1) self.ax4.set_xscale('log') self.ax4.set_yscale('linear') self.ax4.yaxis.set_major_locator(MultipleLocator(ckstep)) if self.skew_limits is None: self.skew_limits=(-10, 10) self.ax4.set_ylim(self.skew_limits) self.ax4.grid(True, alpha=.25, which='both', color=(.25, .25, .25), lw=.25) self.ax4.set_xlabel('Period (s)',fontdict=font_dict) self.ax4.set_ylabel('Skew Angle (deg)',fontdict=font_dict) self.ax4.set_title('Skew Angle',fontdict=font_dictt) #----------------------plotEllipticity-------------------------------- ellipticity = self.pt.ellipticity[0] ellipticityerr = self.pt.ellipticity[1] self.ax5 = self.fig.add_subplot(3, 2, 6, sharex=self.ax2) erskew = self.ax5.errorbar(self._mt.period, ellipticity, marker=self.ellip_marker, ms=self.marker_size, mfc='None', mec=self.ellip_color, mew=self.marker_lw, ls='None', yerr=ellipticityerr, ecolor=self.ellip_color, capsize=self.marker_size, elinewidth=self.marker_lw) #draw a line where the ellipticity is not 2d self.ax5.plot([10**xlimits[0], 10**xlimits[-1]], [self.ellip_cutoff, self.ellip_cutoff], ls='--', color=self.ellip_color, lw=1) self.ax5.set_xscale('log') self.ax5.set_yscale('linear') self.ax5.yaxis.set_major_locator(MultipleLocator(.1)) self.ax5.set_ylim(ymin=0,ymax=1) self.ax5.grid(True, alpha=.25, which='both', color=(.25,.25,.25), lw=.25) self.ax5.set_xlabel('Period (s)',fontdict=font_dict) self.ax5.set_ylabel('$\mathbf{\phi_{max}-\phi_{min}/\phi_{max}+\phi_{min}}$', fontdict=font_dict) self.ax5.set_title('Ellipticity',fontdict=font_dictt) self.fig.suptitle('Phase Tensor Elements for: '+self._mt.station, fontdict={'size':self.font_size+3, 'weight':'bold'})
def plot(self): """ plot residual phase tensor """ # get residual phase tensor for plotting self._compute_residual_pt() # filter data if desired if self.med_filt_kernel is not None: self._apply_median_filter(kernel=self.med_filt_kernel) # set position properties for the plot plt.rcParams["font.size"] = self.font_size plt.rcParams["figure.subplot.left"] = self.subplot_left plt.rcParams["figure.subplot.right"] = self.subplot_right plt.rcParams["figure.subplot.bottom"] = self.subplot_bottom plt.rcParams["figure.subplot.top"] = self.subplot_top plt.rcParams["figure.subplot.wspace"] = self.subplot_wspace plt.rcParams["figure.subplot.hspace"] = self.subplot_hspace # make figure instance self.fig = plt.figure(self.fig_num, self.fig_size, dpi=self.fig_dpi) self.ax = self.fig.add_subplot(1, 1, 1, aspect="equal") # create empty lists to put things into self.stationlist = [] self.offsetlist = [] minlist = [] maxlist = [] plot_periodlist = None # set local parameters with shorter names es = self.ellipse_size ck = self.ellipse_colorby cmap = self.ellipse_cmap ckmin = float(self.ellipse_range[0]) ckmax = float(self.ellipse_range[1]) try: ckstep = float(self.ellipse_range[2]) except IndexError: ckstep = 3 nseg = float((ckmax - ckmin) / (2 * ckstep)) if cmap == "mt_seg_bl2wh2rd": bounds = np.arange(ckmin, ckmax + ckstep, ckstep) # get largest ellipse emax = self._get_ellipse_size_max() # plot phase tensor ellipses for ii, rpt in enumerate(self.residual_pt_list): self.stationlist.append(rpt.station[self.station_id[0] : self.station_id[1]]) # set the an arbitrary origin to compare distance to all other # stations. if ii == 0: east0 = rpt.lon north0 = rpt.lat offset = 0.0 else: east = rpt.lon north = rpt.lat if self.linedir == "ew": if east0 < east: offset = np.sqrt((east0 - east) ** 2 + (north0 - north) ** 2) elif east0 > east: offset = -1 * np.sqrt((east0 - east) ** 2 + (north0 - north) ** 2) else: offset = 0 elif self.linedir == "ns": if north0 < north: offset = np.sqrt((east0 - east) ** 2 + (north0 - north) ** 2) elif north0 > north: offset = -1 * np.sqrt((east0 - east) ** 2 + (north0 - north) ** 2) else: offset = 0 self.offsetlist.append(offset) periodlist = 1.0 / rpt.freq[::-1] phimax = rpt.residual_pt.phimax[0][::-1] phimin = rpt.residual_pt.phimin[0][::-1] azimuth = rpt.residual_pt.azimuth[0][::-1] # get the properties to color the ellipses by if self.ellipse_colorby == "phimin": colorarray = rpt.residual_pt.phimin[0][::-1] elif self.ellipse_colorby == "phimax": colorarray = rpt.residual_pt.phimin[0][::-1] elif self.ellipse_colorby == "phidet": colorarray = np.sqrt(abs(rpt.residual_pt.det[::-1])) * (180 / np.pi) elif self.ellipse_colorby == "skew" or self.ellipse_colorby == "skew_seg": colorarray = rpt.residual_pt.beta[0][::-1] elif self.ellipse_colorby == "ellipticity": colorarray = rpt.residual_pt.ellipticity[::-1] else: raise NameError(self.ellipse_colorby + " is not supported") # get the number of periods n = len(periodlist) if ii == 0: plot_periodlist = periodlist else: if n > len(plot_periodlist): plot_periodlist = periodlist # get min and max of the color array for scaling later minlist.append(min(colorarray)) maxlist.append(max(colorarray)) for jj, ff in enumerate(periodlist): # make sure the ellipses will be visable eheight = phimin[jj] / emax * es ewidth = phimax[jj] / emax * es # create an ellipse scaled by phimin and phimax and orient # the ellipse so that north is up and east is right # need to add 90 to do so instead of subtracting ellipd = patches.Ellipse( (offset * self.xstretch, np.log10(ff) * self.ystretch), width=ewidth, height=eheight, angle=azimuth[jj] - 90, ) # get ellipse color if cmap.find("seg") > 0: ellipd.set_facecolor( mtcl.get_plot_color(colorarray[jj], self.ellipse_colorby, cmap, ckmin, ckmax, bounds=bounds) ) else: ellipd.set_facecolor(mtcl.get_plot_color(colorarray[jj], self.ellipse_colorby, cmap, ckmin, ckmax)) # == =add the ellipse to the plot == ======== self.ax.add_artist(ellipd) # --> Set plot parameters self._plot_periodlist = plot_periodlist n = len(plot_periodlist) # calculate minimum period and maximum period with a stretch factor pmin = np.log10(plot_periodlist.min()) * self.ystretch pmax = np.log10(plot_periodlist.max()) * self.ystretch # need to sort the offsets and station labels so they plot correctly sdtype = [("offset", np.float), ("station", "|S10")] slist = np.array([(oo, ss) for oo, ss in zip(self.offsetlist, self.stationlist)], dtype=sdtype) offset_sort = np.sort(slist, order="offset") self.offsetlist = offset_sort["offset"] self.stationlist = offset_sort["station"] # set y-ticklabels if self.tscale == "period": yticklabels = [ "{0:>4}".format("{0: .1e}".format(plot_periodlist[ll])) for ll in np.arange(0, n, self.ystep) ] + ["{0:>4}".format("{0: .1e}".format(plot_periodlist[-1]))] self.ax.set_ylabel("Period (s)", fontsize=self.font_size + 2, fontweight="bold") elif self.tscale == "frequency": yticklabels = [ "{0:>4}".format("{0: .1e}".format(1.0 / plot_periodlist[ll])) for ll in np.arange(0, n, self.ystep) ] + ["{0:>4}".format("{0: .1e}".format(1.0 / plot_periodlist[-1]))] self.ax.set_ylabel("Frequency (Hz)", fontsize=self.font_size + 2, fontweight="bold") # set x-axis label self.ax.set_xlabel("Station", fontsize=self.font_size + 2, fontweight="bold") # --> set tick locations and labels # set y-axis major ticks self.ax.yaxis.set_ticks([np.log10(plot_periodlist[ll]) * self.ystretch for ll in np.arange(0, n, self.ystep)]) # set y-axis minor ticks self.ax.yaxis.set_ticks( [np.log10(plot_periodlist[ll]) * self.ystretch for ll in np.arange(0, n, 1)], minor=True ) # set y-axis tick labels self.ax.set_yticklabels(yticklabels) # set x-axis ticks self.ax.set_xticks(self.offsetlist * self.xstretch) # set x-axis tick labels as station names xticklabels = self.stationlist if self.xstep != 1: xticklabels = np.zeros(len(self.stationlist), dtype=self.stationlist.dtype) for xx in range(0, len(self.stationlist), self.xstep): xticklabels[xx] = self.stationlist[xx] self.ax.set_xticklabels(xticklabels) # --> set x-limits if self.xlimits == None: self.ax.set_xlim( self.offsetlist.min() * self.xstretch - es * 2, self.offsetlist.max() * self.xstretch + es * 2 ) else: self.ax.set_xlim(self.xlimits) # --> set y-limits if self.ylimits == None: self.ax.set_ylim(pmax + es * 2, pmin - es * 2) else: pmin = np.log10(self.ylimits[0]) * self.ystretch pmax = np.log10(self.ylimits[1]) * self.ystretch self.ax.set_ylim(pmax + es * 2, pmin - es * 2) # --> set title of the plot if self.plot_title == None: pass else: self.ax.set_title(self.plot_title, fontsize=self.font_size + 2) # put a grid on the plot self.ax.grid(alpha=0.25, which="both", color=(0.25, 0.25, 0.25)) # print out the min an max of the parameter plotted print "-" * 25 print ck + " min = {0:.2f}".format(min(minlist)) print ck + " max = {0:.2f}".format(max(maxlist)) print "-" * 25 # ==> make a colorbar with appropriate colors if self.cb_position == None: self.ax2, kw = mcb.make_axes(self.ax, orientation=self.cb_orientation, shrink=0.35) else: self.ax2 = self.fig.add_axes(self.cb_position) if cmap == "mt_seg_bl2wh2rd": # make a color list self.clist = [(cc, cc, 1) for cc in np.arange(0, 1 + 1.0 / (nseg), 1.0 / (nseg))] + [ (1, cc, cc) for cc in np.arange(1, -1.0 / (nseg), -1.0 / (nseg)) ] # make segmented colormap mt_seg_bl2wh2rd = colors.ListedColormap(self.clist) # make bounds so that the middle is white bounds = np.arange(ckmin - ckstep, ckmax + 2 * ckstep, ckstep) # normalize the colors norms = colors.BoundaryNorm(bounds, mt_seg_bl2wh2rd.N) # make the colorbar self.cb = mcb.ColorbarBase( self.ax2, cmap=mt_seg_bl2wh2rd, norm=norms, orientation=self.cb_orientation, ticks=bounds[1:-1] ) else: self.cb = mcb.ColorbarBase( self.ax2, cmap=mtcl.cmapdict[cmap], norm=colors.Normalize(vmin=ckmin, vmax=ckmax), orientation=self.cb_orientation, ) # label the color bar accordingly self.cb.set_label(mtpl.ckdict[ck], fontdict={"size": self.font_size, "weight": "bold"}) # place the label in the correct location if self.cb_orientation == "horizontal": self.cb.ax.xaxis.set_label_position("top") self.cb.ax.xaxis.set_label_coords(0.5, 1.3) elif self.cb_orientation == "vertical": self.cb.ax.yaxis.set_label_position("right") self.cb.ax.yaxis.set_label_coords(1.5, 0.5) self.cb.ax.yaxis.tick_left() self.cb.ax.tick_params(axis="y", direction="in") plt.show()
def add_pt_patch(self, pt_dict): """ Add patches to plot """ plot_x = pt_dict["lon"] plot_y = pt_dict["lat"] w1 = Wedge( (plot_x, plot_y), self.ellipse_size, 90 - pt_dict["azimuth"] - self.wedge_width, 90 - pt_dict["azimuth"] + self.wedge_width, color=mtcolors.get_plot_color( pt_dict["phi_max"], "phimax", self.phimax_cmap, self.phase_limits[0], self.phase_limits[1], ), ) w2 = Wedge( (plot_x, plot_y), self.ellipse_size, 270 - pt_dict["azimuth"] - self.wedge_width, 270 - pt_dict["azimuth"] + self.wedge_width, color=mtcolors.get_plot_color( pt_dict["phi_max"], "phimax", self.phimax_cmap, self.phase_limits[0], self.phase_limits[1], ), ) w3 = Wedge( (plot_x, plot_y), self.ellipse_size * pt_dict["phi_min"] / pt_dict["phi_max"], -1 * pt_dict["azimuth"] - self.wedge_width, -1 * pt_dict["azimuth"] + self.wedge_width, color=mtcolors.get_plot_color( pt_dict["phi_min"], "phimin", self.phimin_cmap, self.phase_limits[0], self.phase_limits[1], ), ) w4 = Wedge( (plot_x, plot_y), self.ellipse_size * pt_dict["phi_min"] / pt_dict["phi_max"], 180 - pt_dict["azimuth"] - self.wedge_width, 180 - pt_dict["azimuth"] + self.wedge_width, color=mtcolors.get_plot_color( pt_dict["phi_min"], "phimin", self.phimin_cmap, self.phase_limits[0], self.phase_limits[1], ), ) if pt_dict["tip_mag_re"] > 0: txr = (pt_dict["tip_mag_re"] * self.arrow_size * np.sin(np.deg2rad(pt_dict["tip_ang_re"]))) tyr = (pt_dict["tip_mag_re"] * self.arrow_size * np.cos(np.deg2rad(pt_dict["tip_ang_re"]))) self.ax.arrow( plot_x, plot_y, txr, tyr, width=self.arrow_lw, facecolor=self.arrow_color_real, edgecolor=(0, 0, 0), length_includes_head=False, head_width=self.arrow_head_width, head_length=self.arrow_head_length, ) txi = (pt_dict["tip_mag_im"] * self.arrow_size * np.sin(np.deg2rad(pt_dict["tip_ang_im"]))) tyi = (pt_dict["tip_mag_im"] * self.arrow_size * np.cos(np.deg2rad(pt_dict["tip_ang_im"]))) self.ax.arrow( plot_x, plot_y, txi, tyi, width=self.arrow_lw, facecolor=self.arrow_color_imag, edgecolor=(0, 0, 0), length_includes_head=False, head_width=self.arrow_head_width, head_length=self.arrow_head_length, ) # make an ellipse e1 = Ellipse( (plot_x, plot_y), width=2 * self.ellipse_size, height=2 * self.ellipse_size * pt_dict["phi_min"] / pt_dict["phi_max"], angle=90 - pt_dict["azimuth"], ) gm = np.sqrt(abs(pt_dict["phi_min"])**2 + abs(pt_dict["phi_max"])**2) e1.set_facecolor( mtcolors.get_plot_color( gm, "geometric_mean", self.gm_cmap, self.phase_limits[0], self.phase_limits[1], )) e1.set_edgecolor( mtcolors.get_plot_color( abs(pt_dict["skew"]), "skew_seg", self.skew_cmap, self.skew_limits[0], self.skew_limits[1], np.arange( self.skew_limits[0], self.skew_limits[1] + self.skew_step, self.skew_step, ), )) e1.set_linewidth(self.skew_lw) e1.set_alpha(self.ellipse_alpha) ### add patches for patch in [e1, w1, w2, w3, w4]: self.ax.add_patch(patch)
def plot(self): """ plot residual phase tensor """ #get residual phase tensor for plotting self._compute_residual_pt() #filter data if desired if self.med_filt_kernel is not None: self._apply_median_filter(kernel=self.med_filt_kernel) #set position properties for the plot plt.rcParams['font.size']=self.font_size plt.rcParams['figure.subplot.left'] = self.subplot_left plt.rcParams['figure.subplot.right'] = self.subplot_right plt.rcParams['figure.subplot.bottom'] = self.subplot_bottom plt.rcParams['figure.subplot.top'] = self.subplot_top plt.rcParams['figure.subplot.wspace'] = self.subplot_wspace plt.rcParams['figure.subplot.hspace'] = self.subplot_hspace #make figure instance self.fig = plt.figure(self.fig_num, self.fig_size, dpi=self.fig_dpi) #create axis instance, be sure to make aspect equal or ellipses will #look funny. self.ax = self.fig.add_subplot(1, 1, 1, aspect='equal') #set local parameters with shorter names es = self.ellipse_size ck = self.ellipse_colorby cmap = self.ellipse_cmap ckmin = float(self.ellipse_range[0]) ckmax = float(self.ellipse_range[1]) try: ckstep = float(self.ellipse_range[2]) except IndexError: ckstep = 3 #set the number of segments in case a segmented map is desired nseg = float((ckmax-ckmin)/(2*ckstep)) if cmap == 'mt_seg_bl2wh2rd': bounds = np.arange(ckmin, ckmax+ckstep, ckstep) #get largest ellipse emax = self.ellipse_scale #emax = self.rpt_array['phimax'].max() #plot phase tensor ellipses for ii, rpt in enumerate(self.rpt_array): phimax = rpt['phimax'] phimin = rpt['phimin'] azimuth = rpt['azimuth'] #get the properties to color the ellipses by try: color_array = rpt[self.ellipse_colorby] except ValueError: raise NameError('{0} is not supported'.format( self.ellipse_colorby)) for jj, ff in enumerate(self.freq_list): if phimin[jj] == 0.0 or phimax[jj] == 0.0: pass else: #make sure the ellipses will be visable eheight = phimin[jj]/emax*es ewidth = phimax[jj]/emax*es #create an ellipse scaled by phimin and phimax and orient #the ellipse so that north is up and east is right #need to add 90 to do so instead of subtracting if self.rot90 == True: ellipd = patches.Ellipse((rpt['offset']*self.xstretch, np.log10(ff)*self.ystretch), width=ewidth, height=eheight, angle=azimuth[jj]-90) else: ellipd = patches.Ellipse((rpt['offset']*self.xstretch, np.log10(ff)*self.ystretch), width=ewidth, height=eheight, angle=azimuth[jj]) #get ellipse color if cmap.find('seg')>0: ellipd.set_facecolor(mtcl.get_plot_color(color_array[jj], self.ellipse_colorby, cmap, ckmin, ckmax, bounds=bounds)) else: ellipd.set_facecolor(mtcl.get_plot_color(color_array[jj], self.ellipse_colorby, cmap, ckmin, ckmax)) # == =add the ellipse to the plot == ======== self.ax.add_artist(ellipd) #--> Set plot parameters #need to sort the offsets and station labels so they plot correctly sdtype = [('offset', np.float), ('station','|S10')] slist = np.array([(oo, ss) for oo, ss in zip(self.rpt_array['offset'], self.rpt_array['station'])], dtype=sdtype) offset_sort = np.sort(slist, order='offset') self.offset_list = offset_sort['offset'] self.station_list = offset_sort['station'] #min and max frequency of the plot pmin = int(np.floor(np.log10(self.freq_list.min()))) pmax = int(np.ceil(np.log10(self.freq_list.max()))) #set y-axis major ticks to be on each power of 10 self.ax.yaxis.set_ticks(np.arange(pmin*self.ystretch, (pmax+1)*self.ystretch, self.ystretch)) #set y-ticklabels to coincide with the desired label if self.tscale == 'period': #make tick labels that will represent period yticklabels = [mtpl.labeldict[-ii] for ii in range(pmin, pmax+1, 1)] self.ax.set_ylabel('Period (s)', fontsize=self.font_size+2, fontweight='bold') elif self.tscale == 'frequency': yticklabels = [mtpl.labeldict[ii] for ii in range(pmin, pmax+1, 1)] self.ax.set_ylabel('Frequency (Hz)', fontsize=self.font_size+2, fontweight='bold') #--> set y-limits if self.ylimits == None: self.ax.set_ylim(pmin*self.ystretch, pmax*self.ystretch) else: pmin = np.log10(self.ylimits[0])*self.ystretch pmax = np.log10(self.ylimits[1])*self.ystretch self.ax.set_ylim(pmin, pmax) #--> set y-axis tick labels self.ax.set_yticklabels(yticklabels) #--> set x-axis label self.ax.set_xlabel('Station', fontsize=self.font_size+2, fontweight='bold') #set x-axis ticks self.ax.set_xticks(self.offset_list*self.xstretch) #set x-axis tick labels as station names xticklabels = self.station_list if self.xstep != 1: xticklabels = np.zeros(len(self.station_list), dtype=self.station_list.dtype) for xx in range(0,len(self.station_list),self.xstep): xticklabels[xx] = self.station_list[xx] self.ax.set_xticklabels(xticklabels) #--> set x-limits if self.xlimits == None: self.ax.set_xlim(self.offset_list.min()*self.xstretch-es*2, self.offset_list.max()*self.xstretch+es*2) else: self.ax.set_xlim(self.xlimits) #--> set title of the plot if self.plot_title == None: pass else: self.ax.set_title(self.plot_title, fontsize=self.font_size+2) #put a grid on the plot self.ax.grid(alpha=.25, which='both', color=(.25, .25, .25)) #==> make a colorbar with appropriate colors if self.cb_position == None: self.ax2, kw = mcb.make_axes(self.ax, orientation=self.cb_orientation, shrink=.35) else: self.ax2 = self.fig.add_axes(self.cb_position) if cmap == 'mt_seg_bl2wh2rd': #make a color list self.clist = [(cc, cc, 1) for cc in np.arange(0, 1+1./(nseg), 1./(nseg))]+\ [(1, cc, cc) for cc in np.arange(1, -1./(nseg), -1./(nseg))] #make segmented colormap mt_seg_bl2wh2rd = colors.ListedColormap(self.clist) #make bounds so that the middle is white bounds = np.arange(ckmin-ckstep, ckmax+2*ckstep, ckstep) #normalize the colors norms = colors.BoundaryNorm(bounds, mt_seg_bl2wh2rd.N) #make the colorbar self.cb = mcb.ColorbarBase(self.ax2, cmap=mt_seg_bl2wh2rd, norm=norms, orientation=self.cb_orientation, ticks=bounds[1:-1]) else: self.cb = mcb.ColorbarBase(self.ax2, cmap=mtcl.cmapdict[cmap], norm=colors.Normalize(vmin=ckmin, vmax=ckmax), orientation=self.cb_orientation) #label the color bar accordingly self.cb.set_label(mtpl.ckdict[ck], fontdict={'size':self.font_size,'weight':'bold'}) #place the label in the correct location if self.cb_orientation == 'horizontal': self.cb.ax.xaxis.set_label_position('top') self.cb.ax.xaxis.set_label_coords(.5, 1.3) elif self.cb_orientation == 'vertical': self.cb.ax.yaxis.set_label_position('right') self.cb.ax.yaxis.set_label_coords(1.5, .5) self.cb.ax.yaxis.tick_left() self.cb.ax.tick_params(axis='y', direction='in') #--> add reference ellipse ref_ellip = patches.Ellipse((0, .0), width=es, height=es, angle=0) ref_ellip.set_facecolor((0, 0, 0)) ref_ax_loc = list(self.ax2.get_position().bounds) ref_ax_loc[0] *= .95 ref_ax_loc[1] -= .17 ref_ax_loc[2] = .1 ref_ax_loc[3] = .1 self.ref_ax = self.fig.add_axes(ref_ax_loc, aspect='equal') self.ref_ax.add_artist(ref_ellip) self.ref_ax.set_xlim(-es/2.*1.05, es/2.*1.05) self.ref_ax.set_ylim(-es/2.*1.05, es/2.*1.05) plt.setp(self.ref_ax.xaxis.get_ticklabels(), visible=False) plt.setp(self.ref_ax.yaxis.get_ticklabels(), visible=False) self.ref_ax.set_title(r'$\Delta \Phi$ = 1') # put the grid lines behind # [line.set_zorder(10000) for line in self.ax.lines] self.ax.set_axisbelow(True) plt.show()
def plot(self, period=0, save2file=None, **kwargs): """ Plot phase tensor maps for data and or response, each figure is of a different period. If response is input a third column is added which is the residual phase tensor showing where the model is not fitting the data well. The data is plotted in km. Args: period: the period index to plot, default=0 Returns: """ print("The input parameter period is", period) # --> read in data first if self.data_obj is None: self._read_files() # set plot properties plt.rcParams['font.size'] = self.font_size plt.rcParams['figure.subplot.left'] = self.subplot_left plt.rcParams['figure.subplot.right'] = self.subplot_right plt.rcParams['figure.subplot.bottom'] = self.subplot_bottom plt.rcParams['figure.subplot.top'] = self.subplot_top font_dict = {'size': self.font_size + 2, 'weight': 'bold'} # make a grid of subplots gs = gridspec.GridSpec(1, 3, hspace=self.subplot_hspace, wspace=self.subplot_wspace) # set some parameters for the colorbar ckmin = float(self.ellipse_range[0]) ckmax = float(self.ellipse_range[1]) try: ckstep = float(self.ellipse_range[2]) except IndexError: if self.ellipse_cmap == 'mt_seg_bl2wh2rd': raise ValueError('Need to input range as (min, max, step)') else: ckstep = 3 bounds = np.arange(ckmin, ckmax + ckstep, ckstep) # set plot limits to be the station area if self.ew_limits is None: east_min = self.data_obj.data_array['rel_east'].min() - \ self.pad_east east_max = self.data_obj.data_array['rel_east'].max() + \ self.pad_east self.ew_limits = (east_min / self.dscale, east_max / self.dscale) if self.ns_limits is None: north_min = self.data_obj.data_array['rel_north'].min() - \ self.pad_north north_max = self.data_obj.data_array['rel_north'].max() + \ self.pad_north self.ns_limits = (north_min / self.dscale, north_max / self.dscale) # -------------plot phase tensors------------------------------------ if period > len(self.plot_period_list) - 1: print("Error: the period exceeds the max value:", len(self.plot_period_list) - 1) # FZ: changed below to plot a given period index # for ff, per in enumerate(self.plot_period_list): for ff, per in enumerate(self.plot_period_list[period:period + 1]): # FZ print(ff, per) print(self.plot_period_list) data_ii = self.period_dict[per] print 'Plotting Period: {0:.5g}'.format(per) fig = plt.figure('{0:.5g}'.format(per), figsize=self.fig_size, dpi=self.fig_dpi) fig.clf() if self.resp_fn is not None: axd = fig.add_subplot(gs[0, 0], aspect='equal') axm = fig.add_subplot(gs[0, 1], aspect='equal') axr = fig.add_subplot(gs[0, 2], aspect='equal') ax_list = [axd, axm, axr] else: axd = fig.add_subplot(gs[0, :], aspect='equal') ax_list = [axd] # plot model below the phase tensors if self.model_fn is not None: gridzcentre = np.mean( [self.model_obj.grid_z[1:], self.model_obj.grid_z[:-1]], axis=0) if self.d_index is not None: approx_depth, d_index = ws.estimate_skin_depth( self.model_obj.res_model.copy(), gridzcentre / self.dscale, per, dscale=self.dscale) else: d_index = self.d_index approx_depth = self.model_obj.grid_z[d_index] # need to add an extra row and column to east and north to make sure # all is plotted see pcolor for details. plot_east = np.append(self.model_obj.grid_east, self.model_obj.grid_east[-1] * 1.25) / \ self.dscale plot_north = np.append(self.model_obj.grid_north, self.model_obj.grid_north[-1] * 1.25) / \ self.dscale # make a mesh grid for plotting # the 'ij' makes sure the resulting grid is in east, north try: self.mesh_east, self.mesh_north = np.meshgrid( plot_east, plot_north, indexing='ij') except TypeError: self.mesh_east, self.mesh_north = [ arr.T for arr in np.meshgrid(plot_east, plot_north) ] for ax in ax_list: plot_res = np.log10(self.model_obj.res_model[:, :, d_index].T) ax.pcolormesh(self.mesh_east, self.mesh_north, plot_res, cmap=self.res_cmap, vmin=self.res_limits[0], vmax=self.res_limits[1]) # --> plot data phase tensors for pt in self.pt_data_arr[data_ii]: eheight = pt['phimin'] / \ self.pt_data_arr[data_ii]['phimax'].max() * \ self.ellipse_size ewidth = pt['phimax'] / \ self.pt_data_arr[data_ii]['phimax'].max() * \ self.ellipse_size ellipse = Ellipse((pt['east'], pt['north']), width=ewidth, height=eheight, angle=90 - pt['azimuth'], **kwargs) # get ellipse color if self.ellipse_cmap.find('seg') > 0: ellipse.set_facecolor( mtcl.get_plot_color(pt[self.ellipse_colorby], self.ellipse_colorby, self.ellipse_cmap, ckmin, ckmax, bounds=bounds)) else: ellipse.set_facecolor( mtcl.get_plot_color(pt[self.ellipse_colorby], self.ellipse_colorby, self.ellipse_cmap, ckmin, ckmax)) axd.add_artist(ellipse) # -----------plot response phase tensors--------------- if self.resp_fn is not None: rcmin = np.floor(self.pt_resid_arr['geometric_mean'].min()) rcmax = np.floor(self.pt_resid_arr['geometric_mean'].max()) for mpt, rpt in zip(self.pt_resp_arr[data_ii], self.pt_resid_arr[data_ii]): eheight = mpt['phimin'] / \ self.pt_resp_arr[data_ii]['phimax'].max() * \ self.ellipse_size ewidth = mpt['phimax'] / \ self.pt_resp_arr[data_ii]['phimax'].max() * \ self.ellipse_size ellipsem = Ellipse((mpt['east'], mpt['north']), width=ewidth, height=eheight, angle=90 - mpt['azimuth'], **kwargs) # get ellipse color if self.ellipse_cmap.find('seg') > 0: ellipsem.set_facecolor( mtcl.get_plot_color(mpt[self.ellipse_colorby], self.ellipse_colorby, self.ellipse_cmap, ckmin, ckmax, bounds=bounds)) else: ellipsem.set_facecolor( mtcl.get_plot_color(mpt[self.ellipse_colorby], self.ellipse_colorby, self.ellipse_cmap, ckmin, ckmax)) axm.add_artist(ellipsem) # -----------plot residual phase tensors--------------- eheight = rpt['phimin'] / \ self.pt_resid_arr[data_ii]['phimax'].max() * \ self.ellipse_size ewidth = rpt['phimax'] / \ self.pt_resid_arr[data_ii]['phimax'].max() * \ self.ellipse_size ellipser = Ellipse((rpt['east'], rpt['north']), width=ewidth, height=eheight, angle=rpt['azimuth'], **kwargs) # get ellipse color rpt_color = np.sqrt(abs(rpt['phimin'] * rpt['phimax'])) if self.ellipse_cmap.find('seg') > 0: ellipser.set_facecolor( mtcl.get_plot_color(rpt_color, 'geometric_mean', self.residual_cmap, ckmin, ckmax, bounds=bounds)) else: ellipser.set_facecolor( mtcl.get_plot_color(rpt_color, 'geometric_mean', self.residual_cmap, ckmin, ckmax)) axr.add_artist(ellipser) # --> set axes properties # data axd.set_xlim(self.ew_limits) axd.set_ylim(self.ns_limits) axd.set_xlabel('Easting ({0})'.format(self.map_scale), fontdict=font_dict) axd.set_ylabel('Northing ({0})'.format(self.map_scale), fontdict=font_dict) # make a colorbar for phase tensors # bb = axd.axes.get_position().bounds bb = axd.get_position().bounds y1 = .25 * (2 + (self.ns_limits[1] - self.ns_limits[0]) / (self.ew_limits[1] - self.ew_limits[0])) cb_location = (3.35 * bb[2] / 5 + bb[0], y1 * self.cb_pt_pad, .295 * bb[2], .02) cbaxd = fig.add_axes(cb_location) cbd = mcb.ColorbarBase(cbaxd, cmap=mtcl.cmapdict[self.ellipse_cmap], norm=Normalize(vmin=ckmin, vmax=ckmax), orientation='horizontal') cbd.ax.xaxis.set_label_position('top') cbd.ax.xaxis.set_label_coords(.5, 1.75) cbd.set_label(mtplottools.ckdict[self.ellipse_colorby]) cbd.set_ticks( np.arange(ckmin, ckmax + self.cb_tick_step, self.cb_tick_step)) axd.text(self.ew_limits[0] * .95, self.ns_limits[1] * .95, 'Data', horizontalalignment='left', verticalalignment='top', bbox={'facecolor': 'white'}, fontdict={'size': self.font_size + 1}) # Model and residual if self.resp_fn is not None: for aa, ax in enumerate([axm, axr]): ax.set_xlim(self.ew_limits) ax.set_ylim(self.ns_limits) ax.set_xlabel('Easting ({0})'.format(self.map_scale), fontdict=font_dict) plt.setp(ax.yaxis.get_ticklabels(), visible=False) # make a colorbar ontop of axis bb = ax.axes.get_position().bounds y1 = .25 * (2 + (self.ns_limits[1] - self.ns_limits[0]) / (self.ew_limits[1] - self.ew_limits[0])) cb_location = (3.35 * bb[2] / 5 + bb[0], y1 * self.cb_pt_pad, .295 * bb[2], .02) cbax = fig.add_axes(cb_location) if aa == 0: cb = mcb.ColorbarBase( cbax, cmap=mtcl.cmapdict[self.ellipse_cmap], norm=Normalize(vmin=ckmin, vmax=ckmax), orientation='horizontal') cb.ax.xaxis.set_label_position('top') cb.ax.xaxis.set_label_coords(.5, 1.75) cb.set_label(mtplottools.ckdict[self.ellipse_colorby]) cb.set_ticks( np.arange(ckmin, ckmax + self.cb_tick_step, self.cb_tick_step)) ax.text(self.ew_limits[0] * .95, self.ns_limits[1] * .95, 'Model', horizontalalignment='left', verticalalignment='top', bbox={'facecolor': 'white'}, fontdict={'size': self.font_size + 1}) else: cb = mcb.ColorbarBase( cbax, cmap=mtcl.cmapdict[self.residual_cmap], norm=Normalize(vmin=rcmin, vmax=rcmax), orientation='horizontal') cb.ax.xaxis.set_label_position('top') cb.ax.xaxis.set_label_coords(.5, 1.75) cb.set_label(r"$\sqrt{\Phi_{min} \Phi_{max}}$") cb_ticks = [rcmin, (rcmax - rcmin) / 2, rcmax] cb.set_ticks(cb_ticks) ax.text(self.ew_limits[0] * .95, self.ns_limits[1] * .95, 'Residual', horizontalalignment='left', verticalalignment='top', bbox={'facecolor': 'white'}, fontdict={'size': self.font_size + 1}) if self.model_fn is not None: for ax in ax_list: ax.tick_params(direction='out') bb = ax.axes.get_position().bounds y1 = .25 * (2 - (self.ns_limits[1] - self.ns_limits[0]) / (self.ew_limits[1] - self.ew_limits[0])) cb_position = (3.0 * bb[2] / 5 + bb[0], y1 * self.cb_res_pad, .35 * bb[2], .02) cbax = fig.add_axes(cb_position) cb = mcb.ColorbarBase(cbax, cmap=self.res_cmap, norm=Normalize( vmin=self.res_limits[0], vmax=self.res_limits[1]), orientation='horizontal') cb.ax.xaxis.set_label_position('top') cb.ax.xaxis.set_label_coords(.5, 1.5) cb.set_label('Resistivity ($\Omega \cdot$m)') cb_ticks = np.arange(np.floor(self.res_limits[0]), np.ceil(self.res_limits[1] + 1), 1) cb.set_ticks(cb_ticks) cb.set_ticklabels( [mtplottools.labeldict[ctk] for ctk in cb_ticks]) if save2file is not None: fig.savefig(save2file, dpi=self.fig_dpi, bbox_inches='tight') plt.show() self.fig_list.append(fig) return fig
def plot(self): """ plots the phase tensor elements """ # Set plot parameters plt.rcParams['font.size'] = self.font_size plt.rcParams['figure.subplot.left'] = .1 plt.rcParams['figure.subplot.right'] = .98 plt.rcParams['figure.subplot.bottom'] = .1 plt.rcParams['figure.subplot.top'] = .95 plt.rcParams['figure.subplot.wspace'] = .21 plt.rcParams['figure.subplot.hspace'] = .5 font_dict = {'size': self.font_size, 'weight': 'bold'} font_dictt = {'size': self.font_size + 2, 'weight': 'bold'} #--> create plot instance self.fig = plt.figure(self.fig_num, self.fig_size, dpi=self.fig_dpi) plt.clf() # get phase tensor instance try: self.pt self.pt.rotate(self.rot_z) except AttributeError: self.pt = self._mt.pt self.pt.rotate(self.rot_z) self.zinv = self._mt.Z.invariants self.zinv.rotate(self.rot_z) cmap = self.ellipse_cmap ckmin = self.ellipse_range[0] ckmax = self.ellipse_range[1] try: ckstep = float(self.ellipse_range[2]) except IndexError: ckstep = 3 if cmap == 'mt_seg_bl2wh2rd': bounds = np.arange(ckmin, ckmax + ckstep, ckstep) nseg = float((ckmax - ckmin) / (2 * ckstep)) # get the properties to color the ellipses by if self.ellipse_colorby == 'phiminang' or \ self.ellipse_colorby == 'phimin': colorarray = self.pt.phimin[0] elif self.ellipse_colorby == 'phidet': colorarray = np.sqrt(abs(self.pt.det[0])) * (180 / np.pi) elif self.ellipse_colorby == 'skew' or\ self.ellipse_colorby == 'skew_seg': colorarray = self.pt.beta[0] elif self.ellipse_colorby == 'ellipticity': colorarray = self.pt.ellipticity[0] else: raise NameError(self.ellipse_colorby + ' is not supported') #-------------plotPhaseTensor----------------------------------- self.ax1 = self.fig.add_subplot(3, 1, 1, aspect='equal') self._mt._period = 1. / self._mt.freq for ii, ff in enumerate(self._mt.period): # make sure the ellipses will be visable if self.pt.phimax[0][ii] != 0: eheight = self.pt.phimin[0][ii] / self.pt.phimax[0][ii] *\ self.ellipse_size ewidth = self.ellipse_size else: # tiny instead of nothing eheight = 0.01 * self.ellipse_size ewidth = 0.01 * self.ellipse_size # ewidth = self.pt.phimax[0][ii]/self.pt.phimax[0][ii]*\ # self.ellipse_size # alternative scaling # eheight = self.pt.phimin[0][ii]/max(np.abs(self.pt.phimax[0]))*\ # self.ellipse_size # ewidth = self.pt.phimax[0][ii]/max(np.abs(self.pt.phimax[0]))*\ # self.ellipse_size # create an ellipse scaled by phimin and phimax and oriented along # the azimuth which is calculated as clockwise but needs to # be plotted counter-clockwise hence the negative sign. ellipd = patches.Ellipse((np.log10(ff) * self.ellipse_spacing, 0), width=ewidth, height=eheight, angle=90 - self.pt.azimuth[0][ii]) self.ax1.add_patch(ellipd) # get ellipse color if cmap.find('seg') > 0: ellipd.set_facecolor( mtcl.get_plot_color(colorarray[ii], self.ellipse_colorby, cmap, ckmin, ckmax, bounds=bounds)) else: ellipd.set_facecolor( mtcl.get_plot_color(colorarray[ii], self.ellipse_colorby, cmap, ckmin, ckmax)) #----set axes properties----------------------------------------------- #--> set tick labels and limits xlimits = (np.floor(np.log10(self._mt.period[0])), np.ceil(np.log10(self._mt.period[-1]))) self.ax1.set_xlim(xlimits) tklabels = [] xticks = [] for tk in self.ax1.get_xticks(): try: tklabels.append(mtpl.labeldict[tk]) xticks.append(tk) except KeyError: pass self.ax1.set_xticks(xticks) self.ax1.set_xticklabels(tklabels, fontdict={'size': self.font_size}) self.ax1.set_xlabel('Period (s)', fontdict=font_dict) self.ax1.set_ylim(ymin=-1.5 * self.ellipse_size, ymax=1.5 * self.ellipse_size) self.ax1.grid(True, alpha=.25, which='major', color=(.25, .25, .25), lw=.25) plt.setp(self.ax1.get_yticklabels(), visible=False) # add colorbar for PT self.cbax = self.fig.add_axes(self.cb_position) if cmap == 'mt_seg_bl2wh2rd': # make a color list clist = [(cc, cc, 1) for cc in np.arange(0, 1 + 1. / (nseg), 1. / (nseg))] +\ [(1, cc, cc) for cc in np.arange(1, -1. / (nseg), -1. / (nseg))] # make segmented colormap mt_seg_bl2wh2rd = colors.ListedColormap(clist) # make bounds so that the middle is white bounds = np.arange(ckmin - ckstep, ckmax + 2 * ckstep, ckstep) # normalize the colors norms = colors.BoundaryNorm(bounds, mt_seg_bl2wh2rd.N) # make the colorbar self.cbpt = mcb.ColorbarBase(self.cbax, cmap=mt_seg_bl2wh2rd, norm=norms, orientation='vertical', ticks=bounds[1:-1]) else: self.cbpt = mcb.ColorbarBase(self.cbax, cmap=mtcl.cmapdict[cmap], norm=colors.Normalize(vmin=ckmin, vmax=ckmax), orientation='vertical') self.cbpt.set_ticks([ckmin, ckmax]) self.cbpt.set_ticklabels( ['{0:.0f}'.format(ckmin), '{0:.0f}'.format(ckmax)]) self.cbpt.ax.yaxis.set_label_position('left') self.cbpt.ax.yaxis.set_label_coords(-1.05, .5) self.cbpt.ax.yaxis.tick_right() self.cbpt.ax.tick_params(axis='y', direction='in') self.cbpt.set_label(mtpl.ckdict[self.ellipse_colorby], fontdict={ 'size': self.font_size, 'weight': 'bold' }) #---------------plotStrikeAngle----------------------------------- self.ax2 = self.fig.add_subplot(3, 2, 3) az = self.pt.azimuth[0] az_err = self.pt.azimuth[1] # put the strike into a coordinate system that goes from -90 to 90 az[np.where(az > 90)] -= 180 az[np.where(az < -90)] += 180 stlist = [] stlabel = [] # plot phase tensor strike ps2 = self.ax2.errorbar(self._mt.period, az, marker=self.strike_pt_marker, ms=self.marker_size, mfc=self.strike_pt_color, mec=self.strike_pt_color, mew=self.marker_lw, ls='none', yerr=az_err, ecolor=self.strike_pt_color, capsize=self.marker_size, elinewidth=self.marker_lw) stlist.append(ps2[0]) stlabel.append('PT') try: strike = self.zinv.strike strikeerr = np.nan_to_num(self.zinv.strike_err) # put the strike into a coordinate system that goes from -90 to 90 strike[np.where(strike > 90)] = strike[np.where(strike > 90)] - 180 strike[np.where( strike < -90)] = strike[np.where(strike < -90)] + 180 # plot invariant strike erxy = self.ax2.errorbar(self._mt.period, strike, marker=self.strike_inv_marker, ms=self.marker_size, mfc=self.strike_inv_color, mec=self.strike_inv_color, mew=self.marker_lw, ls='none', yerr=strikeerr, ecolor=self.strike_inv_color, capsize=self.marker_size, elinewidth=self.marker_lw) stlist.append(erxy[0]) stlabel.append('Z_inv') except AttributeError: print 'Could not get z_invariants from pt, input z if desired.' if self._mt.tipper is not None: # strike from tipper tp = self._mt.Tipper s3 = tp.angle_real + 90 # fold to go from -90 to 90 s3[np.where(s3 > 90)] = s3[np.where(s3 > 90)] - 180 s3[np.where(s3 < -90)] = s3[np.where(s3 < -90)] + 180 # plot strike with error bars ps3 = self.ax2.errorbar(self._mt.period, s3, marker=self.strike_tp_marker, ms=self.marker_size, mfc=self.strike_tp_color, mec=self.strike_tp_color, mew=self.marker_lw, ls='none', yerr=np.zeros_like(s3), ecolor=self.strike_tp_color, capsize=self.marker_size, elinewidth=self.marker_lw) stlist.append(ps3[0]) stlabel.append('Tipper') self.ax2.legend(stlist, stlabel, loc='lower left', markerscale=.5 * self.marker_size, borderaxespad=.01, labelspacing=.1, handletextpad=.2, ncol=len(stlist), borderpad=.1, columnspacing=.1) leg = plt.gca().get_legend() ltext = leg.get_texts() # all the text.Text instance in the legend plt.setp(ltext, fontsize=6) # the legend text fontsize if self.strike_limits is None: self.strike_limits = (-89.99, 89.99) self.ax2.set_yscale('linear') self.ax2.set_xscale('log', nonposx='clip') self.ax2.set_xlim(xmax=10**xlimits[-1], xmin=10**xlimits[0]) self.ax2.set_ylim(self.strike_limits) self.ax2.yaxis.set_major_locator(MultipleLocator(20)) self.ax2.yaxis.set_minor_locator(MultipleLocator(5)) self.ax2.grid(True, alpha=.25, which='both', color=(.25, .25, .25), lw=.25) self.ax2.set_ylabel('Angle (deg)', fontdict=font_dict) self.ax2.set_title('Strike', fontdict=font_dictt) #---------plot Min & Max Phase----------------------------------------- minphi = self.pt.phimin[0] minphierr = self.pt.phimin[1] maxphi = self.pt.phimax[0] maxphierr = self.pt.phimax[1] self.ax3 = self.fig.add_subplot(3, 2, 4, sharex=self.ax2) ermin = self.ax3.errorbar(self._mt.period, minphi, marker=self.ptmin_marker, ms=self.marker_size, mfc='None', mec=self.ptmin_color, mew=self.marker_lw, ls='None', yerr=minphierr, ecolor=self.ptmin_color, capsize=self.marker_size, elinewidth=self.marker_lw) ermax = self.ax3.errorbar(self._mt.period, maxphi, marker=self.ptmax_marker, ms=self.marker_size, mfc='None', mec=self.ptmax_color, mew=self.marker_lw, ls='None', yerr=maxphierr, ecolor=self.ptmax_color, capsize=self.marker_size, elinewidth=self.marker_lw) if self.pt_limits is None: self.pt_limits = [ min([self.pt.phimax[0].min(), self.pt.phimin[0].min()]) - 3, max([self.pt.phimax[0].max(), self.pt.phimin[0].max()]) + 3 ] if self.pt_limits[0] < -10: self.pt_limits[0] = -9.9 if self.pt_limits[1] > 100: self.pt_limits[1] = 99.99 self.ax3.set_xscale('log', nonposx='clip') self.ax3.set_yscale('linear') self.ax3.legend((ermin[0], ermax[0]), ('$\phi_{min}$', '$\phi_{max}$'), loc='lower left', markerscale=.5 * self.marker_size, borderaxespad=.01, labelspacing=.1, handletextpad=.2, ncol=2, borderpad=.01, columnspacing=.01) leg = plt.gca().get_legend() ltext = leg.get_texts() # all the text.Text instance in the legend plt.setp(ltext, fontsize=6.5) # the legend text fontsize self.ax3.set_ylim(self.pt_limits) self.ax3.grid(True, alpha=.25, which='both', color=(.25, .25, .25), lw=.25) self.ax3.set_ylabel('Phase (deg)', fontdict=font_dict) self.ax3.set_title('$\mathbf{\phi_{min}}$ and $\mathbf{\phi_{max}}$', fontdict=font_dictt) #-----------------------plotSkew--------------------------------------- skew = self.pt.beta[0] skewerr = self.pt.beta[1] self.ax4 = self.fig.add_subplot(3, 2, 5, sharex=self.ax2) erskew = self.ax4.errorbar(self._mt.period, skew, marker=self.skew_marker, ms=self.marker_size, mfc='None', mec=self.skew_color, mew=self.marker_lw, ls='None', yerr=skewerr, ecolor=self.skew_color, capsize=self.marker_size, elinewidth=self.marker_lw) # plot lines indicating not 3d self.ax4.plot([10**xlimits[0], 10**xlimits[-1]], [self.skew_cutoff, self.skew_cutoff], ls='--', color=self.skew_color, lw=1) self.ax4.plot([10**xlimits[0], 10**xlimits[-1]], [-self.skew_cutoff, -self.skew_cutoff], ls='--', color=self.skew_color, lw=1) self.ax4.set_xscale('log', nonposx='clip') self.ax4.set_yscale('linear') self.ax4.yaxis.set_major_locator(MultipleLocator(ckstep)) if self.skew_limits is None: self.skew_limits = (-10, 10) self.ax4.set_ylim(self.skew_limits) self.ax4.grid(True, alpha=.25, which='both', color=(.25, .25, .25), lw=.25) self.ax4.set_xlabel('Period (s)', fontdict=font_dict) self.ax4.set_ylabel('Skew Angle (deg)', fontdict=font_dict) self.ax4.set_title('Skew Angle', fontdict=font_dictt) #----------------------plotEllipticity-------------------------------- ellipticity = self.pt.ellipticity[0] ellipticityerr = self.pt.ellipticity[1] self.ax5 = self.fig.add_subplot(3, 2, 6, sharex=self.ax2) erskew = self.ax5.errorbar(self._mt.period, ellipticity, marker=self.ellip_marker, ms=self.marker_size, mfc='None', mec=self.ellip_color, mew=self.marker_lw, ls='None', yerr=ellipticityerr, ecolor=self.ellip_color, capsize=self.marker_size, elinewidth=self.marker_lw) # draw a line where the ellipticity is not 2d self.ax5.plot([10**xlimits[0], 10**xlimits[-1]], [self.ellip_cutoff, self.ellip_cutoff], ls='--', color=self.ellip_color, lw=1) self.ax5.set_xscale('log', nonposx='clip') self.ax5.set_yscale('linear') self.ax5.yaxis.set_major_locator(MultipleLocator(.1)) self.ax5.set_ylim(ymin=0, ymax=1) self.ax5.grid(True, alpha=.25, which='both', color=(.25, .25, .25), lw=.25) self.ax5.set_xlabel('Period (s)', fontdict=font_dict) self.ax5.set_ylabel( '$\mathbf{\phi_{max}-\phi_{min}/\phi_{max}+\phi_{min}}$', fontdict=font_dict) self.ax5.set_title('Ellipticity', fontdict=font_dictt) try: self.fig.suptitle('Phase Tensor Elements for: ' + self._mt.station, fontdict={ 'size': self.font_size + 3, 'weight': 'bold' }) except: self.fig.suptitle('Phase Tensor Elements for Station "unknown"', fontdict={ 'size': self.font_size + 3, 'weight': 'bold' })
def plot(self): """ plot residual phase tensor """ #get residual phase tensor for plotting self._compute_residual_pt() #filter data if desired if self.med_filt_kernel is not None: self._apply_median_filter(kernel=self.med_filt_kernel) #set position properties for the plot plt.rcParams['font.size']=self.font_size plt.rcParams['figure.subplot.left'] = self.subplot_left plt.rcParams['figure.subplot.right'] = self.subplot_right plt.rcParams['figure.subplot.bottom'] = self.subplot_bottom plt.rcParams['figure.subplot.top'] = self.subplot_top plt.rcParams['figure.subplot.wspace'] = self.subplot_wspace plt.rcParams['figure.subplot.hspace'] = self.subplot_hspace #make figure instance if self.tscale == 'period': titlefreq = '{0:.5g} (s)'.format(1./self.plot_freq) else: titlefreq='{0:.5g} (Hz)'.format(self.plot_freq) self.fig = plt.figure(titlefreq, self.fig_size, dpi=self.fig_dpi) #clear the figure if there is already one up plt.clf() #make an axes instance self.ax = self.fig.add_subplot(1, 1, 1, aspect='equal') #--> plot the background image if desired----------------------- try: im = plt.imread(self.image_file) self.ax.imshow(im, origin='lower', extent=self.image_extent, aspect='auto') except AttributeError: pass #get the reference point refpoint = self.plot_reference_point #set some local parameters es = float(self.ellipse_size) cmap = self.ellipse_cmap ckmin = float(self.ellipse_range[0]) ckmax = float(self.ellipse_range[1]) try: ckstep = float(self.ellipse_range[2]) except IndexError: if cmap == 'mt_seg_bl2wh2rd': raise ValueError('Need to input range as (min, max, step)') else: ckstep = 3 nseg = float((ckmax-ckmin)/(2*ckstep)) ck = self.ellipse_colorby #--> set the bounds on the segmented colormap if cmap == 'mt_seg_bl2wh2rd': bounds = np.arange(ckmin, ckmax+ckstep, ckstep) #set tick parameters depending on the mapscale if self.mapscale == 'latlon': self.tickstrfmt = '%.3f' elif self.mapscale == 'eastnorth' or self.mapscale == 'eastnorthkm': self.tickstrfmt = '%.0f' #make some empty arrays elliplist=[] latlist = np.zeros(len(self.residual_pt_list)) lonlist = np.zeros(len(self.residual_pt_list)) self.plot_xarr = np.zeros(len(self.residual_pt_list)) self.plot_yarr = np.zeros(len(self.residual_pt_list)) for ii, rpt in enumerate(self.residual_pt_list): #try to find the freq in the freq list of each file freqfind = [ff for ff, f2 in enumerate(rpt.freq) if f2 > self.plot_freq*(1-self.ftol) and f2 < self.plot_freq*(1+self.ftol)] try: self.jj = freqfind[0] jj = self.jj #--> get size of largest ellipse for this frequency for # normalization to give an indication of the size of # change. emax = self._get_ellipse_size_max(jj) #if map scale is lat lon set parameters if self.mapscale == 'latlon': latlist[ii] = rpt.lat lonlist[ii] = rpt.lon plotx = rpt.lon-refpoint[0] ploty = rpt.lat-refpoint[1] #if map scale is in meters easting and northing elif self.mapscale == 'eastnorth': zone, east, north = utm2ll.LLtoUTM(23, rpt.lat, rpt.lon) #set the first point read in as a refernce other points if ii == 0: zone1 = zone plotx = east-refpoint[0] ploty = north-refpoint[1] #read in all the other point else: #check to make sure the zone is the same this needs #to be more rigorously done if zone1!=zone: print 'Zone change at station '+rpt.station if zone1[0:2] == zone[0:2]: pass elif int(zone1[0:2])<int(zone[0:2]): east += 500000 else: east -= -500000 latlist[ii] = north-refpoint[1] lonlist[ii] = east-refpoint[0] plotx = east-refpoint[0] ploty = north-refpoint[1] else: latlist[ii] = north-refpoint[1] lonlist[ii] = east-refpoint[0] plotx = east-refpoint[0] ploty = north-refpoint[1] #if mapscale is in km easting and northing elif self.mapscale == 'eastnorthkm': zone,east,north = utm2ll.LLtoUTM(23, rpt.lat, rpt.lon) if ii == 0: zone1 = zone plotx = (east-refpoint[0])/1000. ploty = (north-refpoint[1])/1000. else: if zone1!=zone: print 'Zone change at station '+rpt.station if zone1[0:2] == zone[0:2]: pass elif int(zone1[0:2])<int(zone[0:2]): east += 500000 else: east -= 500000 latlist[ii] = (north-refpoint[1])/1000. lonlist[ii] = (east-refpoint[0])/1000. plotx = (east-refpoint[0])/1000. ploty = (north-refpoint[1])/1000. else: latlist[ii] = (north-refpoint[1])/1000. lonlist[ii] = (east-refpoint[0])/1000. plotx = (east-refpoint[0])/1000. ploty = (north-refpoint[1])/1000. else: raise NameError('mapscale not recognized') #put the location of each ellipse into an array in x and y self.plot_xarr[ii] = plotx self.plot_yarr[ii] = ploty #--> set local variables phimin = np.nan_to_num(rpt.residual_pt.phimin[0][jj]) phimax = np.nan_to_num(rpt.residual_pt.phimax[0][jj]) eangle = np.nan_to_num(rpt.residual_pt.azimuth[0][jj]) if cmap == 'mt_seg_bl2wh2rd': bounds = np.arange(ckmin, ckmax+ckstep, ckstep) nseg = float((ckmax-ckmin)/(2*ckstep)) #get the properties to color the ellipses by if self.ellipse_colorby == 'phiminang' or \ self.ellipse_colorby == 'phimin': colorarray = rpt.residual_pt.phimin[0][jj] elif self.ellipse_colorby == 'phidet': colorarray = np.sqrt(abs(rpt.det[0][jj]))*(180/np.pi) elif self.ellipse_colorby == 'skew' or\ self.ellipse_colorby == 'skew_seg': colorarray = rpt.residual_pt.beta[0][jj] elif self.ellipse_colorby == 'ellipticity': colorarray = rpt.residual_pt.ellipticity[0][jj] else: raise NameError(self.ellipse_colorby+' is not supported') #--> get ellipse properties #if the ellipse size is not physically correct make it a dot if phimax == 0 or phimax>100 or phimin == 0 or phimin>100: eheight=.0000001*es ewidth=.0000001*es print rpt.station else: scaling = es/emax eheight = phimin*scaling ewidth = phimax*scaling #make an ellipse ellipd=patches.Ellipse((plotx,ploty), width=ewidth, height=eheight, angle=90-eangle) #get ellipse color if cmap.find('seg')>0: ellipd.set_facecolor(mtcl.get_plot_color(colorarray, self.ellipse_colorby, cmap, ckmin, ckmax, bounds=bounds)) else: ellipd.set_facecolor(mtcl.get_plot_color(colorarray, self.ellipse_colorby, cmap, ckmin, ckmax)) #==> add ellipse to the plot elliplist.append(ellipd) self.ax.add_artist(ellipd) #------------Plot station name------------------------------ try: self.ax.text(plotx, ploty+self.station_pad, rpt.station[self.station_id[0]:self.station_id[1]], horizontalalignment='center', verticalalignment='baseline', fontdict=self.station_font_dict) except AttributeError: pass #==> print a message if couldn't find the freq except IndexError: print 'Did not find {0:.5g} Hz for station {1}'.format( self.plot_freq, rpt.station) #--> set axes properties depending on map scale------------------------ if self.mapscale == 'latlon': self.ax.set_xlabel('longitude', fontsize=self.font_size+2, fontweight='bold') self.ax.set_ylabel('latitude', fontsize=self.font_size+2, fontweight='bold') elif self.mapscale == 'eastnorth': self.ax.set_xlabel('Easting (m)', fontsize=self.font_size+2, fontweight='bold') self.ax.set_ylabel('Northing (m)', fontsize=self.font_size+2, fontweight='bold') elif self.mapscale == 'eastnorthkm': self.ax.set_xlabel('Easting (km)', fontsize=self.font_size+2, fontweight='bold') self.ax.set_ylabel('Northing (km)', fontsize=self.font_size+2, fontweight='bold') #--> set plot limits self.ax.set_xlim(self.plot_xarr.min()-self.xpad, self.plot_xarr.max()+self.xpad) self.ax.set_ylim(self.plot_yarr.min()-self.xpad, self.plot_yarr.max()+self.xpad) #--> set tick label format self.ax.xaxis.set_major_formatter(FormatStrFormatter(self.tickstrfmt)) self.ax.yaxis.set_major_formatter(FormatStrFormatter(self.tickstrfmt)) #--> set title in period or freq if self.tscale == 'period': titlefreq = '{0:.5g} (s)'.format(1./self.plot_freq) else: titlefreq='{0:.5g} (Hz)'.format(self.plot_freq) if not self.plot_title: self.ax.set_title('Phase Tensor Map for '+titlefreq, fontsize=self.font_size+2,fontweight='bold') else: self.ax.set_title(self.plot_title+titlefreq, fontsize=self.font_size+2,fontweight='bold') #make a grid with gray lines self.ax.grid(alpha=.25) #==> make a colorbar with appropriate colors if self.cb_position == None: self.ax2, kw = mcb.make_axes(self.ax, orientation=self.cb_orientation, shrink=.35) else: self.ax2 = self.fig.add_axes(self.cb_position) if cmap == 'mt_seg_bl2wh2rd': #make a color list self.clist = [(cc, cc ,1) for cc in np.arange(0, 1+1./(nseg), 1./(nseg))]+\ [(1, cc, cc) for cc in np.arange(1, -1./(nseg), -1./(nseg))] #make segmented colormap mt_seg_bl2wh2rd = colors.ListedColormap(self.clist) #make bounds so that the middle is white bounds = np.arange(ckmin-ckstep, ckmax+2*ckstep, ckstep) #normalize the colors norms = colors.BoundaryNorm(bounds, mt_seg_bl2wh2rd.N) #make the colorbar self.cb=mcb.ColorbarBase(self.ax2, cmap=mt_seg_bl2wh2rd, norm=norms, orientation=self.cb_orientation, ticks=bounds[1:-1]) else: self.cb=mcb.ColorbarBase(self.ax2, cmap=mtcl.cmapdict[cmap], norm=colors.Normalize(vmin=ckmin, vmax=ckmax), orientation=self.cb_orientation) #label the color bar accordingly self.cb.set_label(mtpl.ckdict[ck], fontdict={'size':self.font_size,'weight':'bold'}) #place the label in the correct location if self.cb_orientation == 'horizontal': self.cb.ax.xaxis.set_label_position('top') self.cb.ax.xaxis.set_label_coords(.5, 1.3) elif self.cb_orientation == 'vertical': self.cb.ax.yaxis.set_label_position('right') self.cb.ax.yaxis.set_label_coords(1.25, .5) self.cb.ax.yaxis.tick_left() self.cb.ax.tick_params(axis='y', direction='in') plt.show()
def plot(self): """ plot residual phase tensor """ # get residual phase tensor for plotting self._get_plot_freq_data() # filter data if desired if self.med_filt_kernel is not None: self._apply_median_filter() # set position properties for the plot plt.rcParams["font.size"] = self.font_size plt.rcParams["figure.subplot.left"] = self.subplot_left plt.rcParams["figure.subplot.right"] = self.subplot_right plt.rcParams["figure.subplot.bottom"] = self.subplot_bottom plt.rcParams["figure.subplot.top"] = self.subplot_top plt.rcParams["figure.subplot.wspace"] = self.subplot_wspace plt.rcParams["figure.subplot.hspace"] = self.subplot_hspace # make figure instance if self.tscale == "period": titlefreq = "{0:.5g} (s)".format(1.0 / self.plot_freq) else: titlefreq = "{0:.5g} (Hz)".format(self.plot_freq) self.fig = plt.figure(titlefreq, self.fig_size, dpi=self.fig_dpi) # clear the figure if there is already one up plt.clf() # make an axes instance self.ax = self.fig.add_subplot(1, 1, 1, aspect="equal") # --> plot the background image if desired----------------------- try: im = plt.imread(self.image_file) self.ax.imshow(im, origin="lower", extent=self.image_extent, aspect="auto") except AttributeError: pass # get the reference point refpoint = self.plot_reference_point # set some local parameters es = float(self.ellipse_size) cmap = self.ellipse_cmap ckmin = float(self.ellipse_range[0]) ckmax = float(self.ellipse_range[1]) try: ckstep = float(self.ellipse_range[2]) except IndexError: if cmap == "mt_seg_bl2wh2rd": raise ValueError("Need to input range as (min, max, step)") else: ckstep = 3 nseg = float((ckmax - ckmin) / (2 * ckstep)) ck = self.ellipse_colorby # --> set the bounds on the segmented colormap if cmap == "mt_seg_bl2wh2rd": bounds = np.arange(ckmin, ckmax + ckstep, ckstep) nseg = float((ckmax - ckmin) / (2 * ckstep)) # set tick parameters depending on the map_scale if self.map_scale == "deg": self.tickstrfmt = "%.3f" elif self.map_scale == "m" or self.map_scale == "km": self.tickstrfmt = "%.0f" # make some empty arrays elliplist = [] self.plot_xarr = np.zeros(len(self.plot_data)) self.plot_yarr = np.zeros(len(self.plot_data)) # --> get size of largest ellipse for this frequency for # normalization to give an indication of the size of # change. emax = self.plot_data[self.ellipse_colorby].max() for ii, rpt in enumerate(self.plot_data): # if map scale is lat lon set parameters if self.map_scale == "deg": plotx = rpt["lon"] - refpoint[0] ploty = rpt["lat"] - refpoint[1] # if map scale is in meters easting and northing elif self.map_scale == "m": zone, east, north = utm2ll.LLtoUTM(23, rpt["lat"], rpt["lon"]) # set the first point read in as a refernce other points if ii == 0: zone1 = zone plotx = east - refpoint[0] ploty = north - refpoint[1] # read in all the other point else: # check to make sure the zone is the same this needs # to be more rigorously done if zone1 != zone: print "Zone change at station {0}".format(rpt["station"]) if zone1[0:2] == zone[0:2]: pass elif int(zone1[0:2]) < int(zone[0:2]): east += 500000 else: east -= -500000 plotx = east - refpoint[0] ploty = north - refpoint[1] else: plotx = east - refpoint[0] ploty = north - refpoint[1] # if map_scale is in km easting and northing elif self.map_scale == "km": zone, east, north = utm2ll.LLtoUTM(23, rpt["lat"], rpt["lon"]) if ii == 0: zone1 = zone plotx = (east - refpoint[0]) / 1000.0 ploty = (north - refpoint[1]) / 1000.0 else: if zone1 != zone: print "Zone change at station {0}".format(rpt["station"]) if zone1[0:2] == zone[0:2]: pass elif int(zone1[0:2]) < int(zone[0:2]): east += 500000 else: east -= 500000 plotx = (east - refpoint[0]) / 1000.0 ploty = (north - refpoint[1]) / 1000.0 else: plotx = (east - refpoint[0]) / 1000.0 ploty = (north - refpoint[1]) / 1000.0 # put the location of each ellipse into an array in x and y self.plot_xarr[ii] = plotx self.plot_yarr[ii] = ploty # --> get ellipse properties # if the ellipse size is not physically correct make it a dot if rpt["phimax"] == 0 or rpt["phimax"] > 100 or rpt["phimin"] == 0 or rpt["phimin"] > 100: eheight = 0.0000001 * es ewidth = 0.0000001 * es print "Bad data at {0}".format(rpt["station"]) else: scaling = es / emax eheight = rpt["phimin"] * scaling ewidth = rpt["phimax"] * scaling # make an ellipse ellipd = patches.Ellipse((plotx, ploty), width=ewidth, height=eheight, angle=self.rot90 - rpt["azimuth"]) # get ellipse color if cmap.find("seg") > 0: ellipd.set_facecolor( mtcl.get_plot_color( rpt[self.ellipse_colorby], self.ellipse_colorby, cmap, ckmin, ckmax, bounds=bounds ) ) else: ellipd.set_facecolor( mtcl.get_plot_color(rpt[self.ellipse_colorby], self.ellipse_colorby, cmap, ckmin, ckmax) ) # ==> add ellipse to the plot elliplist.append(ellipd) self.ax.add_artist(ellipd) # ------------Plot station name------------------------------ try: self.ax.text( plotx, ploty + self.station_pad, rpt["station"][self.station_id[0] : self.station_id[1]], horizontalalignment="center", verticalalignment="baseline", fontdict=self.station_font_dict, ) except AttributeError: pass # --> set axes properties depending on map scale------------------------ if self.map_scale == "deg": self.ax.set_xlabel("Longitude", fontsize=self.font_size + 2, fontweight="bold") self.ax.set_ylabel("Latitude", fontsize=self.font_size + 2, fontweight="bold") elif self.map_scale == "m": self.ax.set_xlabel("Easting (m)", fontsize=self.font_size + 2, fontweight="bold") self.ax.set_ylabel("Northing (m)", fontsize=self.font_size + 2, fontweight="bold") elif self.map_scale == "km": self.ax.set_xlabel("Easting (km)", fontsize=self.font_size + 2, fontweight="bold") self.ax.set_ylabel("Northing (km)", fontsize=self.font_size + 2, fontweight="bold") # --> set plot limits self.ax.set_xlim(self.plot_xarr.min() - self.xpad, self.plot_xarr.max() + self.xpad) self.ax.set_ylim(self.plot_yarr.min() - self.xpad, self.plot_yarr.max() + self.xpad) # --> set tick label format self.ax.xaxis.set_major_formatter(FormatStrFormatter(self.tickstrfmt)) self.ax.yaxis.set_major_formatter(FormatStrFormatter(self.tickstrfmt)) # --> set title in period or freq if self.tscale == "period": titlefreq = "{0:.5g} (s)".format(1.0 / self.plot_freq) else: titlefreq = "{0:.5g} (Hz)".format(self.plot_freq) if not self.plot_title: self.ax.set_title( "Phase Tensor Map for {0}".format(titlefreq), fontsize=self.font_size + 2, fontweight="bold" ) else: self.ax.set_title(self.plot_title + titlefreq, fontsize=self.font_size + 2, fontweight="bold") # make a grid with gray lines self.ax.grid(alpha=0.25) # ==> make a colorbar with appropriate colors if self.cb_position == None: self.ax2, kw = mcb.make_axes(self.ax, orientation=self.cb_orientation, shrink=0.35) else: self.ax2 = self.fig.add_axes(self.cb_position) if cmap == "mt_seg_bl2wh2rd": # make a color list self.clist = [(cc, cc, 1) for cc in np.arange(0, 1 + 1.0 / (nseg), 1.0 / (nseg))] + [ (1, cc, cc) for cc in np.arange(1, -1.0 / (nseg), -1.0 / (nseg)) ] # make segmented colormap mt_seg_bl2wh2rd = colors.ListedColormap(self.clist) # make bounds so that the middle is white bounds = np.arange(ckmin - ckstep, ckmax + 2 * ckstep, ckstep) # normalize the colors norms = colors.BoundaryNorm(bounds, mt_seg_bl2wh2rd.N) # make the colorbar self.cb = mcb.ColorbarBase( self.ax2, cmap=mt_seg_bl2wh2rd, norm=norms, orientation=self.cb_orientation, ticks=bounds[1:-1] ) else: self.cb = mcb.ColorbarBase( self.ax2, cmap=mtcl.cmapdict[cmap], norm=colors.Normalize(vmin=ckmin, vmax=ckmax), orientation=self.cb_orientation, ) # label the color bar accordingly self.cb.set_label(mtpl.ckdict[ck], fontdict={"size": self.font_size, "weight": "bold"}) # place the label in the correct location if self.cb_orientation == "horizontal": self.cb.ax.xaxis.set_label_position("top") self.cb.ax.xaxis.set_label_coords(0.5, 1.3) elif self.cb_orientation == "vertical": self.cb.ax.yaxis.set_label_position("right") self.cb.ax.yaxis.set_label_coords(1.25, 0.5) self.cb.ax.yaxis.tick_left() self.cb.ax.tick_params(axis="y", direction="in") plt.show()
def plot(self): """ plot residual phase tensor """ #get residual phase tensor for plotting self._compute_residual_pt() #filter data if desired if self.med_filt_kernel is not None: self._apply_median_filter(kernel=self.med_filt_kernel) #set position properties for the plot plt.rcParams['font.size']=self.font_size plt.rcParams['figure.subplot.left'] = self.subplot_left plt.rcParams['figure.subplot.right'] = self.subplot_right plt.rcParams['figure.subplot.bottom'] = self.subplot_bottom plt.rcParams['figure.subplot.top'] = self.subplot_top plt.rcParams['figure.subplot.wspace'] = self.subplot_wspace plt.rcParams['figure.subplot.hspace'] = self.subplot_hspace #make figure instance self.fig = plt.figure(self.fig_num, self.fig_size, dpi=self.fig_dpi) self.ax = self.fig.add_subplot(1, 1, 1, aspect='equal') #create empty lists to put things into self.stationlist = [] self.offsetlist = [] minlist = [] maxlist = [] plot_period_list = [] #set local parameters with shorter names es = self.ellipse_size ck = self.ellipse_colorby cmap = self.ellipse_cmap ckmin = float(self.ellipse_range[0]) ckmax = float(self.ellipse_range[1]) try: ckstep = float(self.ellipse_range[2]) except IndexError: ckstep = 3 nseg = float((ckmax-ckmin)/(2*ckstep)) if cmap == 'mt_seg_bl2wh2rd': bounds = np.arange(ckmin, ckmax+ckstep, ckstep) #get largest ellipse emax = self._get_ellipse_size_max() #plot phase tensor ellipses for ii, rpt in enumerate(self.residual_pt_list): self.stationlist.append( rpt.station[self.station_id[0]:self.station_id[1]]) #set the an arbitrary origin to compare distance to all other #stations. if ii == 0: east0 = rpt.lon north0 = rpt.lat offset = 0.0 else: east = rpt.lon north = rpt.lat if self.linedir == 'ew': if east0 < east: offset = np.sqrt((east0-east)**2+(north0-north)**2) elif east0 > east: offset = -1*np.sqrt((east0-east)**2+(north0-north)**2) else: offset = 0 elif self.linedir == 'ns': if north0 < north: offset = np.sqrt((east0-east)**2+(north0-north)**2) elif north0 > north: offset = -1*np.sqrt((east0-east)**2+(north0-north)**2) else: offset = 0 self.offsetlist.append(offset) period_list = 1./rpt.freq[::-1] phimax = rpt.residual_pt.phimax[0][::-1] phimin = rpt.residual_pt.phimin[0][::-1] azimuth = rpt.residual_pt.azimuth[0][::-1] #get the properties to color the ellipses by if self.ellipse_colorby == 'phimin': colorarray = rpt.residual_pt.phimin[0][::-1] elif self.ellipse_colorby == 'phimax': colorarray = rpt.residual_pt.phimin[0][::-1] elif self.ellipse_colorby == 'phidet': colorarray = np.sqrt(abs(rpt.residual_pt.det[::-1]))*(180/np.pi) elif self.ellipse_colorby == 'skew' or\ self.ellipse_colorby == 'skew_seg': colorarray = rpt.residual_pt.beta[0][::-1] elif self.ellipse_colorby == 'ellipticity': colorarray = rpt.residual_pt.ellipticity[::-1] else: raise NameError(self.ellipse_colorby+' is not supported') #get the number of periods n = len(period_list) plot_period_list.extend(list(period_list)) #get min and max of the color array for scaling later minlist.append(min(colorarray)) maxlist.append(max(colorarray)) for jj, ff in enumerate(period_list): #make sure the ellipses will be visable eheight = phimin[jj]/emax*es ewidth = phimax[jj]/emax*es #create an ellipse scaled by phimin and phimax and orient #the ellipse so that north is up and east is right #need to add 90 to do so instead of subtracting if self.rot90 == True: ellipd = patches.Ellipse((offset*self.xstretch, np.log10(ff)*self.ystretch), width=ewidth, height=eheight, angle=azimuth[jj]-90) else: ellipd = patches.Ellipse((offset*self.xstretch, np.log10(ff)*self.ystretch), width=ewidth, height=eheight, angle=azimuth[jj]) #get ellipse color if cmap.find('seg')>0: ellipd.set_facecolor(mtcl.get_plot_color(colorarray[jj], self.ellipse_colorby, cmap, ckmin, ckmax, bounds=bounds)) else: ellipd.set_facecolor(mtcl.get_plot_color(colorarray[jj], self.ellipse_colorby, cmap, ckmin, ckmax)) # == =add the ellipse to the plot == ======== self.ax.add_artist(ellipd) #--> Set plot parameters plot_period_list = np.array(sorted(list(set(plot_period_list)))) self._plot_period_list = plot_period_list n = len(plot_period_list) #calculate minimum period and maximum period with a stretch factor pmin = int(np.floor(np.log10(self._plot_period_list.min()))) pmax = int(np.ceil(np.log10(self._plot_period_list.max()))) #need to sort the offsets and station labels so they plot correctly sdtype = [('offset', np.float), ('station','|S10')] slist = np.array([(oo, ss) for oo, ss in zip(self.offsetlist, self.stationlist)], dtype=sdtype) offset_sort = np.sort(slist, order='offset') self.offsetlist = offset_sort['offset'] self.stationlist = offset_sort['station'] #set y-ticklabels if self.tscale == 'period': yticklabels = [mtpl.labeldict[ii] for ii in range(pmin, pmax+1, 1)] # yticklabels = ['{0:>4}'.format('{0: .1e}'.format(plot_period_list[ll])) # for ll in np.arange(0, n, self.ystep)]+\ # ['{0:>4}'.format('{0: .1e}'.format(plot_period_list[-1]))] self.ax.set_ylabel('Period (s)', fontsize=self.font_size+2, fontweight='bold') elif self.tscale == 'frequency': # yticklabels = ['{0:>4}'.format('{0: .1e}'.format(1./plot_period_list[ll])) # for ll in np.arange(0, n, self.ystep)]+\ # ['{0:>4}'.format('{0: .1e}'.format(1./plot_period_list[-1]))] # yticklabels = [mtpl.labeldict[-ii] for ii in range(pmin, pmax+1, 1)] self.ax.set_ylabel('Frequency (Hz)', fontsize=self.font_size+2, fontweight='bold') #set x-axis label self.ax.set_xlabel('Station', fontsize=self.font_size+2, fontweight='bold') #--> set tick locations and labels #set y-axis major ticks self.ax.yaxis.set_ticks(np.arange(pmin*self.ystretch, (pmax+1)*self.ystretch, self.ystretch)) # self.ax.yaxis.set_ticks([np.log10(plot_period_list[ll])*self.ystretch # for ll in np.arange(0, n, self.ystep)]) #set y-axis minor ticks # self.ax.yaxis.set_ticks([np.log10(plot_period_list[ll])*self.ystretch # for ll in np.arange(0, n, 1)],minor=True) #set y-axis tick labels self.ax.set_yticklabels(yticklabels) #set x-axis ticks self.ax.set_xticks(self.offsetlist*self.xstretch) #set x-axis tick labels as station names xticklabels = self.stationlist if self.xstep != 1: xticklabels = np.zeros(len(self.stationlist), dtype=self.stationlist.dtype) for xx in range(0,len(self.stationlist),self.xstep): xticklabels[xx] = self.stationlist[xx] self.ax.set_xticklabels(xticklabels) #--> set x-limits if self.xlimits == None: self.ax.set_xlim(self.offsetlist.min()*self.xstretch-es*2, self.offsetlist.max()*self.xstretch+es*2) else: self.ax.set_xlim(self.xlimits) #--> set y-limits if self.ylimits == None: self.ax.set_ylim(pmax*self.ystretch, pmin*self.ystretch) else: pmin = np.log10(self.ylimits[0])*self.ystretch pmax = np.log10(self.ylimits[1])*self.ystretch self.ax.set_ylim(pmax, pmin) #--> set title of the plot if self.plot_title == None: pass else: self.ax.set_title(self.plot_title, fontsize=self.font_size+2) #put a grid on the plot self.ax.grid(alpha=.25, which='both', color=(.25, .25, .25)) #print out the min an max of the parameter plotted print '-'*25 print ck+' min = {0:.2f}'.format(min(minlist)) print ck+' max = {0:.2f}'.format(max(maxlist)) print '-'*25 #==> make a colorbar with appropriate colors if self.cb_position == None: self.ax2, kw = mcb.make_axes(self.ax, orientation=self.cb_orientation, shrink=.35) else: self.ax2 = self.fig.add_axes(self.cb_position) if cmap == 'mt_seg_bl2wh2rd': #make a color list self.clist = [(cc, cc, 1) for cc in np.arange(0, 1+1./(nseg), 1./(nseg))]+\ [(1, cc, cc) for cc in np.arange(1, -1./(nseg), -1./(nseg))] #make segmented colormap mt_seg_bl2wh2rd = colors.ListedColormap(self.clist) #make bounds so that the middle is white bounds = np.arange(ckmin-ckstep, ckmax+2*ckstep, ckstep) #normalize the colors norms = colors.BoundaryNorm(bounds, mt_seg_bl2wh2rd.N) #make the colorbar self.cb = mcb.ColorbarBase(self.ax2, cmap=mt_seg_bl2wh2rd, norm=norms, orientation=self.cb_orientation, ticks=bounds[1:-1]) else: self.cb = mcb.ColorbarBase(self.ax2, cmap=mtcl.cmapdict[cmap], norm=colors.Normalize(vmin=ckmin, vmax=ckmax), orientation=self.cb_orientation) #label the color bar accordingly self.cb.set_label(mtpl.ckdict[ck], fontdict={'size':self.font_size,'weight':'bold'}) #place the label in the correct location if self.cb_orientation == 'horizontal': self.cb.ax.xaxis.set_label_position('top') self.cb.ax.xaxis.set_label_coords(.5, 1.3) elif self.cb_orientation == 'vertical': self.cb.ax.yaxis.set_label_position('right') self.cb.ax.yaxis.set_label_coords(1.5, .5) self.cb.ax.yaxis.tick_left() self.cb.ax.tick_params(axis='y', direction='in') plt.show()