def createAARText(self): """Creates the text for airspeed, altitude and climb rate.""" self.airspeedText = self.axes.text( self.rightPos - (self.vertSize / 10.0), -0.97 + (2 * self.vertSize) - (self.vertSize / 10.0), "AS: %.1f m/s" % self.airspeed, color="w", size=self.fontSize, ha="right", ) self.altitudeText = self.axes.text( self.rightPos - (self.vertSize / 10.0), -0.97 + self.vertSize - (0.5 * self.vertSize / 10.0), "ALT: %.1f m " % self.relAlt, color="w", size=self.fontSize, ha="right", ) self.climbRateText = self.axes.text( self.rightPos - (self.vertSize / 10.0), -0.97, "CR: %.1f m/s" % self.climbRate, color="w", size=self.fontSize, ha="right", ) self.airspeedText.set_path_effects([PathEffects.withStroke(linewidth=1, foreground="k")]) self.altitudeText.set_path_effects([PathEffects.withStroke(linewidth=1, foreground="k")]) self.climbRateText.set_path_effects([PathEffects.withStroke(linewidth=1, foreground="k")])
def make_node_label(ax, num, x, max_order): tla = x["node %d TLA"%(num)] # add a rectangle attr = node_attributes[tla] fill_color(ax, 'white') fill_color(ax, attr['color'], alpha=0.6) # add the text txt_core = tla txt = plt.text(0.35,0.5, txt_core, fontsize=fontsize_big, horizontalalignment='center', verticalalignment='center' ) #, backgroundcolor='white', color='black') plt.setp(txt, path_effects=[PathEffects.withStroke(linewidth=3, foreground="w")]) node_order = x["node %d order"%(num)] # if this was an in node, make it an out node if x["node %d inout"%(num)] == 'IN': node_order = max_order[tla] - node_order + 1 txt = plt.text(0.83,0.75, "%d"%node_order, fontsize=fontsize_small, horizontalalignment='center', verticalalignment='center' ) #, backgroundcolor='white', color='black') plt.setp(txt, path_effects=[PathEffects.withStroke(linewidth=3, foreground="w")]) txt = plt.text(0.83,0.38, "-", fontsize=fontsize_small*2, horizontalalignment='center', verticalalignment='center' ) #, backgroundcolor='white', color='black') plt.setp(txt, path_effects=[PathEffects.withStroke(linewidth=3, foreground="w")]) txt = plt.text(0.83,0.25, "%d"%max_order[tla], fontsize=fontsize_small, horizontalalignment='center', verticalalignment='center' ) #, backgroundcolor='white', color='black') plt.setp(txt, path_effects=[PathEffects.withStroke(linewidth=3, foreground="w")]) plt.axis('off') return attr['color']
def spear_marginal_four(stages): """ Plot histograms of the spearman rank for sampled draws from the DPDFs. """ # Plot settings ax_labels = [r'$\rho_{\rm spear}$', r'$f$'] stages_labels = [r'${\rm Starless}$', r'${\rm H_2O \ \ N}$', r'${\rm IR \ \ Y}$', r'${\rm H_2O \ \ Y}$'] colors = ['green', 'SlateBlue', 'red', 'DodgerBlue'] hist_kwargs = {'histtype': 'stepfilled', 'edgecolor': 'black', 'bins': _np.linspace(0, 1, 100)} xcol = 'avg_diam' ycol = 'hco_fwhm' # Calculate ranks good_kdars = ['T', 'F', 'N'] stages = [df[(df[xcol].notnull()) & (df[ycol].notnull()) & ((df['neighbor_KDAR'].isin(good_kdars)) | (df['dpdf_KDAR'].isin(good_kdars)))] for df in stages] spears = [[], [], [], []] for i, stage in enumerate(stages): print i widths = stage[ycol].values # Draw distances radii_samples = dpdf_calc.gen_stage_area_samples(stage, nsample=1e4, radius=True, flatten=False) / 1e6 # Calculate spearman rank for each draw for radii in radii_samples.T: spearman_rank = spearmanr(widths, radii)[0] spears[i].append(spearman_rank) # Begin plot fig, axes = _plt.subplots(figsize=(12, 1.5), nrows=1, ncols=4, sharex=True, sharey=True) for i, ax in enumerate(axes.flatten()): ax.hist(spears[i], facecolor=colors[i], **hist_kwargs) med_spear = _np.median(spears[i]) ax.plot(med_spear, 40, 'Dk', markersize=5) spear_label = r'$\langle\rho_{\rm spear}\rangle_{1/2} = ' \ + str(med_spear)[:4] + r'$' # Plot attributes if i == 0: ax.set_ylabel(ax_labels[1]) ax.set_xlabel(ax_labels[0]) ax.set_xticks([0.2, 0.4, 0.6, 0.8]) ax.set_yticklabels([]) stage_txt = ax.annotate(stages_labels[i], xy=(0.70, 0.75), xycoords='axes fraction', fontsize=10) spear_txt = ax.annotate(spear_label, xy=(0.55, 0.625), xycoords='axes fraction', fontsize=10) stage_txt.set_path_effects([PathEffects.withStroke(linewidth=2, foreground='w')]) spear_txt.set_path_effects([PathEffects.withStroke(linewidth=2, foreground='w')]) _plt.subplots_adjust(top=0.9, bottom=0.25, left=0.1, right=0.9, hspace=0.05, wspace=0.05) _plt.savefig('size_linewidth_spearman_{0}_{1}.pdf'.format('hco', '4panel')) return fig, axes
def plot_all_params(filen='obj_props', out_filen='ppv_grid', log_Z=False): """ Read in the pickled tree parameter dictionary and plot the containing parameters. Parameters ---------- filen : str File name of pickled reduced property dictionary. out_filen : str Basename of plots, the key of the object dictionary is appended to the filename. log_Z : bool Create plots with logarithmic Z axis """ cmap = cm.RdYlBu_r obj_dict = pickle.load(open(filen + '.pickle', 'rb')) X = obj_dict['velo'] Y = obj_dict['angle'] X = ndimage.zoom(X, 3) Y = ndimage.zoom(Y, 3) W = ndimage.zoom(obj_dict['conflict_frac'], 3) obj_dict['reward'] = np.log10(obj_dict['new_kdar_assoc']) / obj_dict['conflict_frac'] params = [(k, v) for k, v in obj_dict.iteritems() if k not in ['velo', 'angle']] clevels = [0.06, 0.12, 0.20, 0.30, 0.5] for key, Z in params: print ':: ', key fig, ax = plt.subplots(figsize=(4, 4.5)) cax = fig.add_axes([0.15, 0.88, 0.8, 0.03]) plt.subplots_adjust(top=0.85, left=0.15, right=0.95, bottom=0.125) if log_Z: Z = np.log10(Z) key += '_(log)' Z = ndimage.zoom(Z, 3) pc = ax.pcolor(X, Y, Z, cmap=cmap, vmin=Z.min(), vmax=Z.max()) cb = plt.colorbar(pc, ax=ax, cax=cax, orientation='horizontal', ticklocation='top') ax.plot([4], [0.065], 'ko', ms=10, markerfacecolor='none', markeredgewidth=2) # Contours for conflict frac cn = ax.contour(X, Y, W, levels=clevels, colors='k', linewidth=2) plt.setp(cn.collections, path_effects=[PathEffects.withStroke(linewidth=2, foreground='w')]) cl = ax.clabel(cn, fmt='%1.2f', inline=1, fontsize=10, use_clabeltext=True) plt.setp(cl, path_effects=[PathEffects.withStroke(linewidth=2, foreground='w')]) # Labels ax.set_xlabel(r'$v \ \ [{\rm km \ s^{-1}}]$') ax.set_ylabel(r'$\theta \ \ [^{\circ}]$') # Limits ax.set_xlim([X.min(), X.max()]) ax.set_ylim([Y.min(), Y.max()]) # Save plt.savefig(out_filen + '_' + key + '.pdf') plt.savefig(out_filen + '_' + key + '.png', dpi=300) plt.close()
def createRPYText(self): '''Creates the text for roll, pitch and yaw.''' self.rollText = self.axes.text(self.leftPos+(self.vertSize/10.0),-0.97+(2*self.vertSize)-(self.vertSize/10.0),'Roll: %.2f' % self.roll,color='w',size=self.fontSize) self.pitchText = self.axes.text(self.leftPos+(self.vertSize/10.0),-0.97+self.vertSize-(0.5*self.vertSize/10.0),'Pitch: %.2f' % self.pitch,color='w',size=self.fontSize) self.yawText = self.axes.text(self.leftPos+(self.vertSize/10.0),-0.97,'Yaw: %.2f' % self.yaw,color='w',size=self.fontSize) self.rollText.set_path_effects([PathEffects.withStroke(linewidth=1,foreground='k')]) self.pitchText.set_path_effects([PathEffects.withStroke(linewidth=1,foreground='k')]) self.yawText.set_path_effects([PathEffects.withStroke(linewidth=1,foreground='k')])
def createAARText(self): '''Creates the text for airspeed, altitude and climb rate.''' self.airspeedText = self.axes.text(self.rightPos-(self.vertSize/10.0),-0.97+(2*self.vertSize)-(self.vertSize/10.0),'AS: %.1f m/s' % self.airspeed,color='w',size=self.fontSize,ha='right') self.altitudeText = self.axes.text(self.rightPos-(self.vertSize/10.0),-0.97+self.vertSize-(0.5*self.vertSize/10.0),'ALT: %.1f m ' % self.relAlt,color='w',size=self.fontSize,ha='right') self.climbRateText = self.axes.text(self.rightPos-(self.vertSize/10.0),-0.97,'CR: %.1f m/s' % self.climbRate,color='w',size=self.fontSize,ha='right') self.airspeedText.set_path_effects([PathEffects.withStroke(linewidth=1,foreground='k')]) self.altitudeText.set_path_effects([PathEffects.withStroke(linewidth=1,foreground='k')]) self.climbRateText.set_path_effects([PathEffects.withStroke(linewidth=1,foreground='k')])
def spear_size_linewidth_four(stages): """ """ # TODO add doc ax_labels = [r'$R \ \ [{\rm pc}]$', r'$\Delta v_{\rm HCO^+} \ \ [{\rm km \ s^{-1}}]$'] stages_labels = [r'${\rm Starless}$', r'${\rm H_2O \ \ N}$', r'${\rm IR \ \ Y}$', r'${\rm H_2O \ \ Y}$'] colors = ['green', 'SlateBlue', 'red', 'DodgerBlue'] xcol = 'avg_diam' ycol = 'hco_fwhm' # Plot limits stages = [df[(df[xcol].notnull()) & (df[ycol].notnull())] for df in stages] xmin = _np.nanmin([df[xcol].min() for df in stages]) xmax = _np.nanmax([df[xcol].max() for df in stages]) ymin = _np.nanmin([df[ycol].min() for df in stages]) ymax = _np.nanmax([df[ycol].max() for df in stages]) spears = [spearmanr(df[xcol].values, df[ycol].values) for df in stages] spears = [str(i[0])[:4] for i in spears] spears = [r'$\rho_{\rm spear} = ' + s + r'$' for s in spears] # Plot settings error_kwargs = {'elinewidth': 0.5, 'ecolor': 'black', 'capsize': 0, 'fmt': 'D', 'ms': 2.5} # Begin plot fig, axes = _plt.subplots(figsize=(12, 4), nrows=1, ncols=4, sharex=True, sharey=True) for i, ax in enumerate(axes.flatten()): # Error bar plot x = stages[i][xcol].values y = stages[i][ycol].values xerr = stages[i][xcol].values * 0.1 yerr = stages[i][ycol + '_err'].values ax.errorbar(x, y, xerr=xerr, yerr=yerr, color=colors[i], **error_kwargs) linex = _np.linspace(0.01, 30, 100) liney = linex**(0.50) * 2.0 ax.plot(linex, liney, 'k--', alpha=0.5) # Plot attributes ax.set_xlim([10**(_np.log10(xmin) - 0.2), 10**(_np.log10(xmax) + 0.2)]) ax.set_ylim([10**(_np.log10(ymin) - 0.2), 10**(_np.log10(ymax) + 0.2)]) ax.set_xscale('log') ax.set_yscale('log') ax.set_xlabel(ax_labels[0]) if i == 0: ax.set_ylabel(ax_labels[1]) stage_txt = ax.annotate(stages_labels[i], xy=(0.70, 0.90), xycoords='axes fraction', fontsize=10) spear_txt = ax.annotate(spears[i], xy=(0.65, 0.85), xycoords='axes fraction', fontsize=10) stage_txt.set_path_effects([PathEffects.withStroke(linewidth=2, foreground='w')]) spear_txt.set_path_effects([PathEffects.withStroke(linewidth=2, foreground='w')]) _plt.subplots_adjust(top=0.9, bottom=0.15, left=0.1, right=0.9, hspace=0.05, wspace=0.05) _plt.savefig('size_linewidth_{0}_{1}.pdf'.format('hco', '4panel')) return fig, axes
def test_patheffect2(): ax2 = plt.subplot(111) arr = np.arange(25).reshape((5, 5)) ax2.imshow(arr) cntr = ax2.contour(arr, colors="k") plt.setp(cntr.collections, path_effects=[withStroke(linewidth=3, foreground="w")]) clbls = ax2.clabel(cntr, fmt="%2.0f", use_clabeltext=True) plt.setp(clbls, path_effects=[withStroke(linewidth=3, foreground="w")])
def createBatteryBar(self): '''Creates the bar to display current battery percentage.''' self.batOutRec = patches.Rectangle((self.rightPos-(1.3+self.rOffset)*self.batWidth,1.0-(0.1+1.0+(2*0.075))*self.batHeight),self.batWidth*1.3,self.batHeight*1.15,facecolor='darkgrey',edgecolor='none') self.batInRec = patches.Rectangle((self.rightPos-(self.rOffset+1+0.15)*self.batWidth,1.0-(0.1+1+0.075)*self.batHeight),self.batWidth,self.batHeight,facecolor='lawngreen',edgecolor='none') self.batPerText = self.axes.text(self.rightPos - (self.rOffset+0.65)*self.batWidth,1-(0.1+1+(0.075+0.15))*self.batHeight,'%.f' % self.batRemain,color='w',size=self.fontSize,ha='center',va='top') self.batPerText.set_path_effects([PathEffects.withStroke(linewidth=1,foreground='k')]) self.voltsText = self.axes.text(self.rightPos-(self.rOffset+1.3+0.2)*self.batWidth,1-(0.1+0.05+0.075)*self.batHeight,'%.1f V' % self.voltage,color='w',size=self.fontSize,ha='right',va='top') self.ampsText = self.axes.text(self.rightPos-(self.rOffset+1.3+0.2)*self.batWidth,1-self.vertSize-(0.1+0.05+0.1+0.075)*self.batHeight,'%.1f A' % self.current,color='w',size=self.fontSize,ha='right',va='top') self.voltsText.set_path_effects([PathEffects.withStroke(linewidth=1,foreground='k')]) self.ampsText.set_path_effects([PathEffects.withStroke(linewidth=1,foreground='k')]) self.axes.add_patch(self.batOutRec) self.axes.add_patch(self.batInRec)
def setup(dpi=300, sketch=(1, 100, 2), theme='light'): """Setup travelmaps.""" # Customized plt.xkcd()-settings # http://jakevdp.github.io/blog/2013/07/10/XKCD-plots-in-matplotlib rcParams['font.family'] = ['Humor Sans', 'Comic Sans MS'] rcParams['font.size'] = 8.0 rcParams['path.sketch'] = sketch rcParams['axes.linewidth'] = 1.0 rcParams['lines.linewidth'] = 1.0 rcParams['grid.linewidth'] = 0.0 rcParams['axes.unicode_minus'] = False if theme=='dark': rcParams['path.effects'] = [patheffects.withStroke(linewidth=2, foreground="k")] rcParams['figure.facecolor'] = 'black' rcParams['figure.edgecolor'] = 'black' rcParams['lines.color'] = 'white' rcParams['patch.edgecolor'] = 'white' rcParams['text.color'] = 'white' rcParams['axes.facecolor'] = 'black' rcParams['axes.edgecolor'] = 'white' rcParams['axes.labelcolor'] = 'white' rcParams['xtick.color'] = 'white' rcParams['ytick.color'] = 'white' rcParams['grid.color'] = 'white' rcParams['savefig.facecolor'] = 'black' rcParams['savefig.edgecolor'] = 'black' else: rcParams['path.effects'] = [patheffects.withStroke(linewidth=2, foreground="w")] rcParams['figure.facecolor'] = 'white' rcParams['figure.edgecolor'] = 'white' rcParams['lines.color'] = 'black' rcParams['patch.edgecolor'] = 'black' rcParams['text.color'] = 'black' rcParams['axes.facecolor'] = 'white' rcParams['axes.edgecolor'] = 'black' rcParams['axes.labelcolor'] = 'black' rcParams['xtick.color'] = 'black' rcParams['ytick.color'] = 'black' rcParams['grid.color'] = 'black' rcParams['savefig.facecolor'] = 'white' rcParams['savefig.edgecolor'] = 'white' # *Bayesian Methods for Hackers*-colour-cylce # (https://github.com/pkgpl/PythonProcessing/blob/master/results/matplotlibrc.bmh.txt) rcParams['axes.prop_cycle'] = plt.cycler('color', ['#348ABD', '#A60628', '#7A68A6', '#467821', '#D55E00', '#CC79A7', '#56B4E9', '#009E73', '#F0E442', '#0072B2']) # Adjust dpi, so figure on screen and savefig looks the same rcParams['figure.dpi'] = dpi rcParams['savefig.dpi'] = dpi
def createBatteryBar(self): """Creates the bar to display current battery percentage.""" self.batOutRec = patches.Rectangle( (self.rightPos - (1.3 + self.rOffset) * self.batWidth, 1.0 - (0.1 + 1.0 + (2 * 0.075)) * self.batHeight), self.batWidth * 1.3, self.batHeight * 1.15, facecolor="darkgrey", edgecolor="none", ) self.batInRec = patches.Rectangle( (self.rightPos - (self.rOffset + 1 + 0.15) * self.batWidth, 1.0 - (0.1 + 1 + 0.075) * self.batHeight), self.batWidth, self.batHeight, facecolor="lawngreen", edgecolor="none", ) self.batPerText = self.axes.text( self.rightPos - (self.rOffset + 0.65) * self.batWidth, 1 - (0.1 + 1 + (0.075 + 0.15)) * self.batHeight, "%.f" % self.batRemain, color="w", size=self.fontSize, ha="center", va="top", ) self.batPerText.set_path_effects([PathEffects.withStroke(linewidth=1, foreground="k")]) self.voltsText = self.axes.text( self.rightPos - (self.rOffset + 1.3 + 0.2) * self.batWidth, 1 - (0.1 + 0.05 + 0.075) * self.batHeight, "%.1f V" % self.voltage, color="w", size=self.fontSize, ha="right", va="top", ) self.ampsText = self.axes.text( self.rightPos - (self.rOffset + 1.3 + 0.2) * self.batWidth, 1 - self.vertSize - (0.1 + 0.05 + 0.1 + 0.075) * self.batHeight, "%.1f A" % self.current, color="w", size=self.fontSize, ha="right", va="top", ) self.voltsText.set_path_effects([PathEffects.withStroke(linewidth=1, foreground="k")]) self.ampsText.set_path_effects([PathEffects.withStroke(linewidth=1, foreground="k")]) self.axes.add_patch(self.batOutRec) self.axes.add_patch(self.batInRec)
def test_patheffect1(): ax1 = plt.subplot(111) ax1.imshow([[1, 2], [2, 3]]) txt = ax1.annotate("test", (1., 1.), (0., 0), arrowprops=dict(arrowstyle="->", connectionstyle="angle3", lw=2), size=20, ha="center", path_effects=[path_effects.withStroke(linewidth=3, foreground="w")]) txt.arrow_patch.set_path_effects([path_effects.Stroke(linewidth=5, foreground="w"), path_effects.Normal()]) pe = [path_effects.withStroke(linewidth=3, foreground="w")] ax1.grid(True, linestyle="-", path_effects=pe)
def test_patheffects(): mpl.rcParams['path.effects'] = [ patheffects.withStroke(linewidth=4, foreground='w')] fig, ax = plt.subplots() ax.plot([1, 2, 3]) with io.BytesIO() as ps: fig.savefig(ps, format='ps')
def visualize_contours(x, y, dx, dy, p, **kwargs): """ visualize contours in two dimensions """ title = 'contour plot: ' if 'title' in kwargs: title += kwargs['title'] density = 1.0 if 'density' in kwargs: density = kwargs['density'] cmap = 'gist_earth' if 'cmap' in kwargs: cmap = kwargs['cmap'] linewidth = 0.5 ##10 * hypot(dx, dy) if 'linewidth' in kwargs: linewidth = kwargs['linewidth'] fig, ax = subplots() ax.streamplot(x, y, dx, dy, color=p, density=density, cmap=cmap, linewidth=linewidth) cont = ax.contour(x, y, p, cmap=cmap, vmin=p.min(), vmax=p.max()) labels = ax.clabel(cont) setp(labels, path_effects=[withStroke(linewidth=8, foreground='w')]) ax.set(aspect=1, title=title) show()
def plotter(fdict): """ Go """ COOP = psycopg2.connect(database='coop', host='iemdb', user='******') ccursor = COOP.cursor(cursor_factory=psycopg2.extras.DictCursor) station = fdict.get('station', 'IA0000') table = "alldata_%s" % (station[:2],) nt = network.Table("%sCLIMATE" % (station[:2],)) ccursor.execute(""" WITH avgs as ( SELECT sday, avg(high) from """ + table + """ WHERE station = %s GROUP by sday) SELECT year, sum(case when o.high > a.avg then 1 else 0 end), count(*) from """ + table + """ o, avgs a WHERE o.station = %s and o.sday = a.sday and extract(doy from day) < extract(doy from now()) GROUP by year ORDER by year ASC """, (station, station)) years = [] data = [] for row in ccursor: years.append(row['year']) data.append(float(row['sum']) / float(row['count']) * 100.) data = np.array(data) years = np.array(years) (fig, ax) = plt.subplots(1, 1) avgv = np.average(data) colorabove = 'r' colorbelow = 'b' bars = ax.bar(years - 0.4, data, fc=colorabove, ec=colorabove) for i, bar in enumerate(bars): if data[i] < avgv: bar.set_facecolor(colorbelow) bar.set_edgecolor(colorbelow) ax.axhline(avgv, lw=2, color='k', zorder=2) txt = ax.text(years[10], avgv, "Avg: %.1f%%" % (avgv,), color='yellow', fontsize=14, va='center') txt.set_path_effects([PathEffects.withStroke(linewidth=5, foreground="k")]) ax.set_ylim(0, 100) ax.set_yticks([0, 10, 25, 50, 75, 90, 100]) ax.set_xlabel("Year") ax.set_xlim(min(years)-1, max(years)+1) ax.set_ylabel("Frequency [%]") ax.grid(True) today = datetime.date.today() msg = ("[%s] %s %s-%s Frequency of Days above Long Term Average 1 Jan - %s" ) % (station, nt.sts[station]['name'], min(years), max(years), today.strftime("%-d %b")) tokens = msg.split() sz = len(tokens) / 2 ax.set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:])) return fig
def draw_graticule_labels(self): phi = np.array([-179.999,-150.,-120.,-90.,-60.,-30.,0.0, 30.0,60.,90.,120.,150.,179.99]) phi_labels = ['-180','-150','-120','-90','-60','-30','0', '30','60','90','120','150','180'] phi = 180.+np.array([-179.999,-120.,-60.,0.0, 60.0,120.,179.99]) phi_labels = ['-180','-120','-60','0', '60','120','180'] th = np.array([-60,-30,30,60]) import matplotlib.patheffects as path_effects ef = path_effects.withStroke(foreground="w", linewidth=2) # text.set_path_effects([ef]) for p,l in zip(phi,phi_labels): plt.gca().projtext(np.pi/2.,np.radians(p+180.), l,color='k',ha='center', fontsize=12,path_effects=[ef]) for t in th: plt.gca().projtext(np.radians(t)-np.pi/2.,np.pi, '%.0f'%(t),color='k',ha='center', fontsize=12,path_effects=[ef])
def __annotate_plot(self, x, y): self.__clear_markers() if x is None or y is None: return start, stop = self.axes.get_xlim() textX = ((stop - start) / 50.0) + x text = '{}\n{}'.format(*format_precision(self.settings, x, y, fancyUnits=True)) if matplotlib.__version__ < '1.3': self.axes.annotate(text, xy=(x, y), xytext=(textX, y), ha='left', va='top', size='x-small', gid='peak') self.axes.plot(x, y, marker='x', markersize=10, color='w', mew=3, gid='peak') self.axes.plot(x, y, marker='x', markersize=10, color='r', gid='peak') else: effect = patheffects.withStroke(linewidth=2, foreground="w", alpha=0.75) self.axes.annotate(text, xy=(x, y), xytext=(textX, y), ha='left', va='top', size='x-small', path_effects=[effect], gid='peak') self.axes.plot(x, y, marker='x', markersize=10, color='r', path_effects=[effect], gid='peak')
def __plot_peak(self, peakF, peakL, peakT): self.__clear_markers() y = utc_to_mpl(peakT) start, stop = self.axes.get_xlim() textX = ((stop - start) / 50.0) + peakF when = format_time(peakT) text = '{}\n{}\n{when}'.format(*format_precision(self.settings, peakF, peakL, fancyUnits=True), when=when) if matplotlib.__version__ < '1.3': self.axes.annotate(text, xy=(peakF, y), xytext=(textX, y), ha='left', va='bottom', size='x-small', color='w', gid='peakText') self.axes.plot(peakF, y, marker='x', markersize=10, color='w', mew=3, gid='peakShadow') self.axes.plot(peakF, y, marker='x', markersize=10, color='r', gid='peak') else: effect = patheffects.withStroke(linewidth=2, foreground="w", alpha=0.75) self.axes.annotate(text, xy=(peakF, y), xytext=(textX, y), ha='left', va='bottom', size='x-small', path_effects=[effect], gid='peakText') self.axes.plot(peakF, y, marker='x', markersize=10, color='r', path_effects=[effect], gid='peak')
def plot_single_circle_grid(centroids, radiuses, ax, intensities, grid=True, alpha=0.75): # intensities = np.ma.masked_equal(abs(np.array(intensities)), .0) patches = [] count = 0 if grid: for n, x in enumerate(centroids): for y, r in zip(centroids, radiuses): # ax.text(x, y, count) count += 1 circle = Circle((x, y), r) patches.append(circle) else: for xy, r in zip(centroids, radiuses): count += 1 circle = Circle(xy, r) patches.append(circle) sorted_index = [idx for (intensity, idx) in sorted(zip(intensities, range(len(intensities))))] patches = [patches[idx] for idx in sorted_index] intensities = [intensities[idx] for idx in sorted_index] norm = mpl.colors.Normalize(vmin=0.0, vmax=max(intensities)) cm.jet.set_bad(color='white', alpha=0.0) colors = [('white')] + [(cm.jet(i)) for i in xrange(1, 256)] new_map = mpl.colors.LinearSegmentedColormap.from_list('new_map', colors, N=256) p = PatchCollection(patches, cmap=new_map, alpha=alpha, norm=norm, linewidth=0) p.set_array(np.array(intensities)) ax.add_collection(p) ax.annotate(int(np.sqrt(count)), xy=(2, 90), fontsize=30, path_effects=[PathEffects.withStroke(linewidth=3, foreground="w")])
def __annotate_plot(self): f, l, t = self.extent.get_peak_flt() when = format_time(t) tPos = utc_to_mpl(t) text = '{}\n{}\n{when}'.format(*format_precision(self.settings, f, l, fancyUnits=True), when=when) if matplotlib.__version__ < '1.3': self.axes.text(f, tPos, l, text, ha='left', va='bottom', size='x-small', gid='peak') self.axes.plot([f], [tPos], [l], marker='x', markersize=10, mew=3, color='w', gid='peak') self.axes.plot([f], [tPos], [l], marker='x', markersize=10, color='r', gid='peak') else: effect = patheffects.withStroke(linewidth=2, foreground="w", alpha=0.75) self.axes.text(f, tPos, l, text, ha='left', va='bottom', size='x-small', gid='peak', path_effects=[effect]) self.axes.plot([f], [tPos], [l], marker='x', markersize=10, color='r', gid='peak', path_effects=[effect])
def __plot_peak(self, peakF, peakL, peakT): when = format_time(peakT) tPos = utc_to_mpl(peakT) text = '{}\n{}\n{when}'.format(*format_precision(self.settings, peakF, peakL, fancyUnits=True), when=when) if matplotlib.__version__ < '1.3': self.axes.text(peakF, tPos, peakL, text, ha='left', va='bottom', size='x-small', gid='peakText') self.axes.plot([peakF], [tPos], [peakL], marker='x', markersize=10, mew=3, color='w', gid='peak') self.axes.plot([peakF], [tPos], [peakL], marker='x', markersize=10, color='r', gid='peakShadow') else: effect = patheffects.withStroke(linewidth=2, foreground="w", alpha=0.75) self.axes.text(peakF, tPos, peakL, text, ha='left', va='bottom', size='x-small', gid='peakText', path_effects=[effect]) self.axes.plot([peakF], [tPos], [peakL], marker='x', markersize=10, color='r', gid='peak', path_effects=[effect])
def __generate_lable_plot(self, lbl, plot): for y in range(0, lbl.shape[0]): for x in range(0, lbl.shape[1]): if lbl[y][x] != 0: t=plot.text(x,y,lbl[y][x], fontsize=12, horizontalalignment='center', verticalalignment='center') #add white stroke around the font plt.setp(t, path_effects=[PathEffects.withStroke(linewidth=3, foreground="w")])
def labels(self, vecs, labels=None, *args, **kwargs): vecs = np.asarray(vecs) kwargs.setdefault("ha", "center") kwargs.setdefault("va", "bottom") kwargs.setdefault("clip_on", True) import matplotlib.patheffects as PathEffects kwargs.setdefault("path_effects", [PathEffects.withStroke(linewidth=2, foreground="w")]) if labels is None: labels = [str(v) for v in vecs] elif callable(labels): labels = [labels(v) for v in vecs] order = np.argsort(vlen(vecs)) labels = np.asarray(labels) keys = [] values = [] for k,v in kwargs.items(): if isinstance(v, np.ndarray): keys.append(k) values.append(v[order]) del kwargs[k] done = set() for values in zip(vecs[order], labels[order], *values): v, l = values[:2] if keys: kwargs2 = dict(zip(keys, values[2:])) kwargs2.update(kwargs) else: kwargs2 = kwargs self.text(v, l, done=done, **kwargs2)
def addLabel(ax, label=None, loc=1, stroke=False, size=None, prop=None, **kwargs): from matplotlib.offsetbox import AnchoredText from matplotlib.patheffects import withStroke from string import lowercase warn('Deprecated function: use Figure or Axes class methods.') # expand list if not isinstance(ax,(list,tuple)): ax = [ax] l = len(ax) if not isinstance(label,(list,tuple)): label = [label]*l if not isinstance(loc,(list,tuple)): loc = [loc]*l if not isinstance(stroke,(list,tuple)): stroke = [stroke]*l # settings if prop is None: prop = dict() if not size: prop['size'] = 18 args = dict(pad=0., borderpad=1.5, frameon=False) args.update(kwargs) # cycle over axes at = [] # list of texts for i in xrange(l): if label[i] is None: label[i] = '('+lowercase[i]+')' elif isinstance(label[i],int): label[i] = '('+lowercase[label[i]]+')' # create label at.append(AnchoredText(label[i], loc=loc[i], prop=prop, **args)) ax[i].add_artist(at[i]) # add to axes if stroke[i]: at[i].txt._text.set_path_effects([withStroke(foreground="w", linewidth=3)]) return at
def make_colorbar(clevs, norm, cmap): """ Manual Color Bar """ ax = plt.axes([0.92, 0.1, 0.05, 0.8], frameon=False, yticks=[], xticks=[]) under = clevs[0]-(clevs[1]-clevs[0]) over = clevs[-1]+(clevs[-1]-clevs[-2]) blevels = np.concatenate([[under, ], clevs, [over, ]]) cb2 = mpcolorbar.ColorbarBase(ax, cmap=cmap, norm=norm, boundaries=blevels, extend='both', ticks=None, spacing='uniform', orientation='vertical') for i, lev in enumerate(clevs): y = float(i) / (len(clevs) - 1) fmt = '%g' txt = cb2.ax.text(0.5, y, fmt % (lev,), va='center', ha='center') txt.set_path_effects([PathEffects.withStroke(linewidth=2, foreground="w")]) ax.yaxis.set_ticklabels([]) ax.set_ylabel("Power Differential [kW]")
def plot_wrapper(model, resolution, ax, nonzero_frequency_mask): xy = [] r = [] w = [] f = [] for year in range(2003, 2011): _, test, coefficients, circle_parameters = read_results(model, year, resolution) latlons, radiuses, features = zip(*circle_parameters) radiuses = np.array(radiuses) / 10. xy.extend(latlons) r.extend(radiuses.tolist()) w.extend(coefficients) f.extend(features) w = np.power(w, 2) heatmap = earth_to_square(xy, r, w, f, nonzero_frequency_mask) # ax = plt.subplot(1, 1, 1, aspect='equal') # plot_single_circle_grid(centers, radiuses, ax, intensities, grid=False, alpha=0.2) image = ax.pcolormesh(heatmap, cmap='jet') # plt.title("Wrapped Ridge (WR)", fontsize=14) plt.ylim((0, 112)) plt.xlim((0, 112)) plt.xticks([]) plt.yticks([]) ax.annotate(int(resolution), xy=(4, 98), fontsize=30, path_effects=[PathEffects.withStroke(linewidth=3, foreground="w")]) # plt.savefig("/Users/mecl/gp_mecl/exp/swe/heatmap_ridge.pdf") # plt.show() return image
def annotate_plot(self): self.clear_markers() fMax, lMax, tMax = self.extent.get_peak_flt() y = epoch_to_mpl(tMax) start, stop = self.axes.get_xlim() textX = ((stop - start) / 50.0) + fMax when = format_time(fMax) if(matplotlib.__version__ < '1.3'): self.axes.annotate('{0:.6f}MHz\n{1:.2f}dB\n{2}'.format(fMax, lMax, when), xy=(fMax, y), xytext=(textX, y), ha='left', va='bottom', size='small', color='w', gid='peak') self.axes.plot(fMax, y, marker='x', markersize=10, color='w', mew=3, gid='peak') self.axes.plot(fMax, y, marker='x', markersize=10, color='r', gid='peak') else: effect = patheffects.withStroke(linewidth=3, foreground="w", alpha=0.75) self.axes.annotate('{0:.6f}MHz\n{1:.2f}dB\n{2}'.format(fMax, lMax, when), xy=(fMax, y), xytext=(textX, y), ha='left', va='bottom', size='small', path_effects=[effect], gid='peak') self.axes.plot(fMax, y, marker='x', markersize=10, color='r', path_effects=[effect], gid='peak')
def circle(x, y, radius=0.15): from matplotlib.patches import Circle from matplotlib.patheffects import withStroke circle = Circle((x, y), radius, clip_on=False, zorder=10, linewidth=1, edgecolor='black', facecolor=(0, 0, 0, .0125), path_effects=[withStroke(linewidth=5, foreground='w')]) ax.add_artist(circle)
def main(): # URL of NASA GIBS URL = 'http://gibs.earthdata.nasa.gov/wmts/epsg4326/best/wmts.cgi' wmts = WebMapTileService(URL) # Layers for MODIS true color and snow RGB layers = ['MODIS_Terra_SurfaceReflectance_Bands143', 'MODIS_Terra_CorrectedReflectance_Bands367'] date_str = '2016-02-05' # Plot setup plot_CRS = ccrs.Mercator() geodetic_CRS = ccrs.Geodetic() x0, y0 = plot_CRS.transform_point(4.6, 43.1, geodetic_CRS) x1, y1 = plot_CRS.transform_point(11.0, 47.4, geodetic_CRS) ysize = 8 xsize = 2 * ysize * (x1 - x0) / (y1 - y0) fig = plt.figure(figsize=(xsize, ysize), dpi=100) for layer, offset in zip(layers, [0, 0.5]): ax = fig.add_axes([offset, 0, 0.5, 1], projection=plot_CRS) ax.set_xlim((x0, x1)) ax.set_ylim((y0, y1)) ax.add_wmts(wmts, layer, wmts_kwargs={'time': date_str}) txt = ax.text(4.7, 43.2, wmts[layer].title, fontsize=18, color='wheat', transform=geodetic_CRS) txt.set_path_effects([PathEffects.withStroke(linewidth=5, foreground='black')]) plt.show()
def __annotate_plot(self, x, y): self.__clear_markers() if x is None or y is None: return start, stop = self.axes.get_xlim() textX = ((stop - start) / 50.0) + x text = '{0:.6f} MHz\n{1:.2f} $\mathsf{{dB/\sqrt{{Hz}}}}$'.format(x, y) if matplotlib.__version__ < '1.3': self.axes.annotate(text, xy=(x, y), xytext=(textX, y), ha='left', va='top', size='x-small', gid='peak') self.axes.plot(x, y, marker='x', markersize=10, color='w', mew=3, gid='peak') self.axes.plot(x, y, marker='x', markersize=10, color='r', gid='peak') else: effect = patheffects.withStroke(linewidth=2, foreground="w", alpha=0.75) self.axes.annotate(text, xy=(x, y), xytext=(textX, y), ha='left', va='top', size='x-small', path_effects=[effect], gid='peak') self.axes.plot(x, y, marker='x', markersize=10, color='r', path_effects=[effect], gid='peak')
def main(): # simple timer for log file start = time.time() script = os.path.basename(sys.argv[0]) task = 'Create preliminary validation report' print(task) engine = create_engine(f"postgresql://{db_user}:{db_pwd}@{db_host}/{db}") required_file = '../collaborator_report/_static/cities_data.tex' if not os.path.exists(required_file): sys.exit( f'''The file {required_file} doesn't appear to exist. This implies that all required scripts for the cities defined in the region_settings workskeet of the _project_configuration.xlsx file have not been successfully run, or at least the script '_all_cities_summary_tex_tables_for_report.py' which generates required tables for this script probably hasn't. Please ensure that the tables 'cities_data.tex' and 'cities_summary_statistics.tex' have both been generated before proceeding.''' ) # Create maps (Web Mercator epsg 3857, for basemap purposes) # Plot study region (after projecting to web mercator) # basemap = 'https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png' # basemap_attribution = "Map tiles by Carto, under CC BY 3.0. Data by OpenStreetMap, under ODbL." basemap = [ ctx.providers.Esri.WorldImagery, ctx.providers.Esri.WorldImagery.attribution ] city = gpd.GeoDataFrame.from_postgis('SELECT * FROM city', engine, geom_col='geom').to_crs(epsg=3857) urban = gpd.GeoDataFrame.from_postgis('SELECT * FROM urban_region', engine, geom_col='geom').to_crs(epsg=3857) urban_study_region = gpd.GeoDataFrame.from_postgis( 'SELECT * FROM urban_study_region_pop', engine, geom_col='geom').to_crs(epsg=3857) bounding_box = box(*buffered_box(urban_study_region.total_bounds, 500)) urban_buffer = gpd.GeoDataFrame(gpd.GeoSeries(bounding_box), columns=['geometry'], crs=3857) clip_box = transforms.Bbox.from_extents(*urban_buffer.total_bounds) xmin, ymin, xmax, ymax = urban_study_region.total_bounds scaling = set_scale(urban_study_region.total_bounds) if not os.path.exists( f'../data/study_region/{study_region}/{study_region}_m_urban_boundary.png' ): f, ax = plt.subplots(figsize=(10, 10), edgecolor='k') urban.plot(ax=ax, color='yellow', label='Urban centre (GHS)', alpha=0.4) urban_study_region.plot(ax=ax, facecolor="none", hatch='///', label='Urban study region', alpha=0.5) city.plot(ax=ax, label='Administrative boundary', facecolor="none", edgecolor='white', lw=2) ax.set_title(f'Study region boundary for {full_locale}', fontsize=12) plt.axis('equal') # map_attribution = 'Administrative boundary (attribution to be added) | Urban centres (Global Human Settlements Urban Centre Database UCDB R2019A) | {basemap_attribution}'.format(basemap_attribution = basemap[1]) map_attribution = basemap[1] ctx.add_basemap(ax, source=basemap[0], attribution='') ax.text( 0.005, 0.005, map_attribution, transform=ax.transAxes, size=attribution_size, path_effects=[patheffects.withStroke(linewidth=2, foreground="w")], wrap=False) scalebar = AnchoredSizeBar(ax.transData, scaling['distance'], scaling['display'], 'lower right', pad=2, color='white', frameon=False, size_vertical=1, fontproperties=fontprops) ax.add_artist(scalebar) ax.set_axis_off() plt.tight_layout() ax.figure.savefig( f'../data/study_region/{study_region}/{study_region}_m_urban_boundary.png', bbox='tight', pad_inches=.2, dpi=dpi) ax.clear() # Other plots basemap = [ ctx.providers.Stamen.TonerLite, ctx.providers.Stamen.TonerHybrid.attribution ] if not os.path.exists( f'../data/study_region/{study_region}/{study_region}_m_pos.png'): # Plot public open space sql = ''' SELECT geom_public geom FROM open_space_areas WHERE geom_public IS NOT NULL AND ST_IsValid(geom_public) AND NOT ST_IsEmpty(geom_public) AND ST_GeometryType(geom_public) IN ('ST_Polygon','ST_MultiPolygon') AND aos_ha_public > 0.000001; ''' pos = gpd.GeoDataFrame.from_postgis(sql, engine, geom_col='geom').to_crs(epsg=3857) urban_pos = gpd.overlay(pos, urban_buffer, how='intersection') f, ax = plt.subplots(figsize=(10, 10), edgecolor='k') urban_study_region.plot(ax=ax, facecolor="none", label='Urban study region', alpha=1, edgecolor='black', lw=2) urban_pos.plot(ax=ax, color='green', label='Public Open Space (POS)', alpha=0.7) plt.axis([xmin, xmax, ymin, ymax]) ax.set_title(f'Public open space of urban {full_locale}', fontsize=12) plt.axis('equal') map_attribution = 'Open space data: OpenStreetMap contributors, 2019 | {basemap_attribution}'.format( basemap_attribution=basemap[1]) ctx.add_basemap(ax, source=basemap[0], attribution='', alpha=0.5) ax.text( 0.005, 0.005, map_attribution, transform=ax.transAxes, size=attribution_size, path_effects=[patheffects.withStroke(linewidth=2, foreground="w")], wrap=False) scalebar = AnchoredSizeBar(ax.transData, scaling['distance'], scaling['display'], 'lower right', pad=1.2, color='black', frameon=False, size_vertical=1, fontproperties=fontprops) ax.add_artist(scalebar) ax.set_axis_off() plt.tight_layout() ax.figure.savefig( f'../data/study_region/{study_region}/{study_region}_m_pos.png', bbox='tight', pad_inches=.2, dpi=dpi) ax.clear() # hexplot pop_hex = gpd.GeoDataFrame.from_postgis('SELECT * FROM pop_ghs_2015', engine, geom_col='geom').to_crs(epsg=3857) urban_hex = gpd.overlay(pop_hex, urban_buffer, how='intersection') if not os.path.exists( f'../data/study_region/{study_region}/{study_region}_m_popdens.png' ): f, ax = plt.subplots(figsize=(10, 10), edgecolor='k') urban_hex.dropna(subset=['pop_per_sqkm']).plot( ax=ax, column='pop_per_sqkm', cmap='Blues', label='Population density', alpha=0.4) urban_study_region.plot(ax=ax, facecolor="none", label='Urban study region', alpha=1, edgecolor='black', lw=2) plt.axis([xmin, xmax, ymin, ymax]) ax.set_title( f'Population density estimate per km² in urban {full_locale}', fontsize=12) plt.axis('equal') map_attribution = 'Population data (2015): GHS, 2019 | {basemap_attribution}'.format( basemap_attribution=basemap[1]) ctx.add_basemap(ax, source=basemap[0], attribution='', alpha=0.5) ax.text( 0.005, 0.005, map_attribution, transform=ax.transAxes, size=attribution_size, path_effects=[patheffects.withStroke(linewidth=2, foreground="w")], wrap=False) scalebar = AnchoredSizeBar(ax.transData, scaling['distance'], scaling['display'], 'lower right', pad=1.2, color='black', frameon=False, size_vertical=1, fontproperties=fontprops) ax.add_artist(scalebar) ax.set_axis_off() # Create colorbar as a legend vmin, vmax = urban_hex['pop_per_sqkm'].min( ), urban_hex['pop_per_sqkm'].max() # sm = plt.cm.ScalarMappable(cmap=’Blues’, norm=plt.Normalize(vmin=vmin, vmax=vmax)) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) sm = plt.cm.ScalarMappable(cmap='Blues', norm=plt.Normalize(vmin=vmin, vmax=vmax)) # empty array for the data range sm._A = [] # add the colorbar to the figure cbar = ax.figure.colorbar(sm, cax=cax, fraction=0.046, pad=0.04) plt.tight_layout() ax.figure.savefig( f'../data/study_region/{study_region}/{study_region}_m_popdens.png', bbox='tight', pad_inches=.2, dpi=dpi) ax.clear() ## manually defining the destination list to ensure desired order destinations = [('fresh_food_market', 'Fresh Food / Market'), ('convenience', 'Convenience'), ('pt_any', 'Public transport stop (any)')] for dest in destinations: dest_name = dest[0] if not os.path.exists( f'../data/study_region/{study_region}/{study_region}_m_{dest_name}.png' ): dest_name_full = dest[1] # print(dest[1]) f, ax = plt.subplots(figsize=(10, 10), edgecolor='k') urban_hex.dropna(subset=[f'count_{dest_name}']).plot( ax=ax, column=f'count_{dest_name}', cmap='viridis_r', label='{dest_name_full} count', alpha=0.7) urban_study_region.plot(ax=ax, facecolor="none", label='Urban study region', alpha=1, edgecolor='black', lw=2) plt.axis([xmin, xmax, ymin, ymax]) ax.set_title(f'{dest_name_full} count in urban {full_locale}', fontsize=12) plt.axis('equal') map_attribution = 'Population data (2015): GHS, 2019 | {basemap_attribution}'.format( basemap_attribution=basemap[1]) ctx.add_basemap(ax, source=basemap[0], attribution='', alpha=0.5) ax.text(0.005, 0.005, map_attribution, transform=ax.transAxes, size=attribution_size, path_effects=[ patheffects.withStroke(linewidth=2, foreground="w") ], wrap=False) scalebar = AnchoredSizeBar(ax.transData, scaling['distance'], scaling['display'], 'lower right', pad=1.2, color='black', frameon=False, size_vertical=1, fontproperties=fontprops) ax.add_artist(scalebar) ax.set_axis_off() # Create colorbar as a legend vmin, vmax = urban_hex[f'count_{dest_name}'].min( ), urban_hex[f'count_{dest_name}'].max() # sm = plt.cm.ScalarMappable(cmap=’Blues’, norm=plt.Normalize(vmin=vmin, vmax=vmax)) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) sm = plt.cm.ScalarMappable(cmap='viridis_r', norm=plt.Normalize(vmin=vmin, vmax=vmax)) # empty array for the data range sm._A = [] # add the colorbar to the figure cbar = ax.figure.colorbar( sm, cax=cax, fraction=0.046, pad=0.04, ticks=np.arange(np.min(urban_hex[f'count_{dest_name}']), np.max(urban_hex[f'count_{dest_name}']) + 1)) plt.tight_layout() ax.figure.savefig( f'../data/study_region/{study_region}/{study_region}_m_{dest_name}.png', bbox='tight', pad_inches=.2, dpi=dpi) ax.clear() # Render report sql = ''' SELECT dest_name, dest_name_full, (osm_id IS NOT NULL)::boolean AS osm_sourced, COALESCE(COUNT(d.*),0) count FROM destinations d, urban_study_region u WHERE ST_DWithin(d.geom,u.geom,500) GROUP BY dest_name, dest_name_full, osm_sourced; ''' dest_counts = pd.read_sql(sql, engine, index_col='dest_name') urban_area = urban_study_region.area_sqkm[0] urban_pop = int(urban_study_region.urban_pop_est[0]) urban_pop_dens = urban_study_region.pop_per_sqkm[0] # # Study region context if areas[analysis_scale]['data'].startswith('GHS:'): # Cities like Maiduguri, Seattle and Baltimore have urban areas defined by GHS query = areas[analysis_scale]['data'].replace('GHS:', '') blurb = ( f'The urban portion of the city of {full_locale} was defined ' 'using the Global Human Settlements (GHS, 2019) urban centre ' f'layer for 2015 filtered using the query, {query}.' f'Urban {full_locale} has an area of ' f'{urban_area:,.2f} km² and had a population estimate of approximately ' f'{urban_pop:,} persons in 2015, or {urban_pop_dens:,.2f} per km².' ) desc_sr = ( f'The GHS urban centre (yellow shading) of {full_locale} was used ' 'to define the study region (cross-hatching} used for analysis of ' f'liveability in {full_locale}.') elif not_urban_intersection: # urban area defined using supplied administrative boundary only. # The main reason for this option being taken is that the administrative boundary # for a city (e.g. Vic) does not correspond with any area in the GHS urban layer. blurb = ( f'The administrative boundary for {full_locale} was used as the ' f'urban study region for analysis purposes. Unlike other cities, it was not possible ' 'to use the Global Human Settlements (GHS, 2019) urban centre layer to define ' "the city's urban extent. " f'Urban {full_locale} has an area of ' f'{urban_area:,.2f} km² and had a population estimate of approximately ' f'{urban_pop:,} persons in 2015, or {urban_pop_dens:,.2f} per km².' ) desc_sr = ('The administrative boundary (white outline) ' 'was used to define the ' 'study region (cross-hatching} used for analysis of ' f'liveability in {full_locale}.') else: # intersection of GHS urban area with administrative boundary blurb = ( f'The urban portion of the city of {full_locale} was defined ' 'as the intersection of its administrative boundary ' 'and the Global Human Settlements (GHS, 2019) urban centre ' f'layer for 2015 :cite:`ghs_ucl_data`. Urban {full_locale} has an area of ' f'{urban_area:,.2f} km² and had a population estimate of approximately ' f'{urban_pop:,} persons in 2015, or {urban_pop_dens:,.2f} per km² :cite:`ghs_pop_method,ghs_pop_data`.' ) desc_sr = ( 'The intersection of administrative boundary (white outline) ' 'and urban centre (yellow shading) areas was used to define the ' 'study region (cross-hatching} used for analysis of ' f'liveability in {full_locale}.') desc_pop = ('Spatial distribution of relative population density ' '(estimated population per square kilometre) ' f'for {full_locale}.') rst = ( f'Study region context\r\n^^^^^^^^^^^^^^^^^^^^\r\n\r\n' f'{blurb}\r\n\r\n' f'.. figure:: ../data/study_region/{study_region}/{study_region}_m_urban_boundary.png\r\n' ' :width: 70%\r\n' ' :align: center\r\n\r\n' f' {desc_sr}\r\n\r\n' f'.. figure:: ../data/study_region/{study_region}/{study_region}_m_popdens.png\r\n' ' :width: 70%\r\n' ' :align: center\r\n\r\n' f' {desc_pop}\r\n\r\n' f'Destinations\r\n^^^^^^^^^^^^\r\n\r\n' 'Destinations sourced from OpenStreetMap (OSM) were identified using key-value pair tags. ' 'Please see the :ref:`osm` section for more information, ' 'including links to guidelines for these categories and for ' 'country specific coding guidelines.\r\n') if (custom_destinations != '') and custom_destinations_attribution != '': rst = f"{rst}Additional custom sourced destinations specific to the {full_locale} context were included in analyses using data collated with the assistance of {custom_destinations_attribution}.\r\n" for d in destinations: dest_name = d[0] dest_name_full = d[1] dest_underline = '~' * len(dest_name_full) dest_count = dest_counts.loc[dest_name, 'count'].sum() intro = destination_tags[dest_name] if dest_count == 0: rst = f'{rst}\r\n{intro}\r\nFor the city of {full_locale}, no destinations of this type were identified within a 500 metres Euclidean distance buffer of the urban study region boundary using OpenStreetMap data with the above listed key-value pair tags.' if custom_destinations not in ['', 'nan']: rst = f'{rst} Nor were destinations of this type included based on the custom data source specified in the configuration file.' else: dest_count_list = {} sources = ['custom', 'OSM'] for l in [True, False]: dest_count_check = dest_counts.query( f"(dest_name_full=='{dest_name_full}') & (osm_sourced=={str(l)})" )['count'] if len(dest_count_check) == 0: dest_count_list[sources[l]] = 0 else: dest_count_list[sources[l]] = dest_count_check[0] blurb = f"Within a 500 metres Euclidean distance buffer of {full_locale}'s urban study region boundary the count of {dest_name_full} destinations identified using OpenStreetMap data was {dest_count_list['OSM']:,}." if custom_destinations not in ['', 'nan']: blurb = f"{blurb} Using custom data, the {dest_name_full} count within this distance was {dest_count_list['custom']:,}." blurb = f'{blurb}\r\n\r\nPlease note that Euclidean distance analysis of destination counts was only undertaken in order to enumerate destinations within proximal distance of the city in order to produce this report; all indicators of access will be evaluated using network distance for sample points at regular intervals along the street network, prior to aggregation of estimates at small area and city scales.' desc_dest = f'Destinations defined using key-value pair tags (listed above) were extracted from matching OpenStreetMap points or polygon centroids to comprise the category of \'{dest_name_full}\'. Aggregate counts of destinations within each cell of a 250m hex grid was undertaken to illustrate the spatial distribution of the identified data points.' rst = ( f'{rst}\r\n\r\n{dest_name_full}\r\n{dest_underline}\r\n\r\n' f'{intro}\r\n{blurb}\r\n\r\n' f'.. figure:: ../data/study_region/{study_region}/{study_region}_m_{dest_name}.png\r\n' ' :width: 70%\r\n' ' :align: center\r\n\r\n' f' {desc_dest}\r\n\r\n') # POS blurb = destination_tags['pos'] desc_pos = f'For the city of {full_locale}, areas of public open space identified in {full_locale} have been plotted in green in the above map.' rst = ( f'{rst}\r\n\r\nPublic open space\r\n~~~~~~~~~~~~~~~~~\r\n\r\n' f'{blurb}\r\n\r\n' f'.. figure:: ../data/study_region/{study_region}/{study_region}_m_pos.png\r\n' ' :width: 70%\r\n' ' :align: center\r\n\r\n' f' {desc_pos}\r\n\r\n') # Finally, we'll reference the bibliography under assumption this is the final chapter in report rst = (f'{rst}\r\n\r\n' '.. bibliography:: references.bib\r\n' ' :style: unsrt\r\n\r\n') with open("../collaborator_report/report.rst", "w") as text_file: print(f"{rst}", file=text_file) index_rst = ('.. Global Liveability collaborator report template\r\n\r\n' 'Global Liveability Indicators\r\n' '=============================\r\n\r\n' f'About\r\n' '*****\r\n' '.. toctree:: \r\n' ' :maxdepth: 3 \r\n' ' :caption: Contents: \r\n\r\n' ' about \r\n' ' dest_summary \r\n\r\n' f'{full_locale}\r\n' '{full_locale_underline}\r\n\r\n' '.. toctree:: \r\n' ' :maxdepth: 4 \r\n\r\n' ' report \r\n').format(full_locale=full_locale, full_locale_underline='*' * len(full_locale)) with open("../collaborator_report/index.rst", "w") as text_file: print(f"{index_rst}", file=text_file) line_prepender('../collaborator_report/conf_template.py', '../collaborator_report/conf.py', get_sphinx_conf_header()) city = full_locale.lower().replace(' ', '') make = ( "make clean" " && make latexpdf" f" && cp _build/latex/globalliveabilityindicatorspreliminaryreport{city}.pdf " f" ../data/study_region/{study_region}/global_liveability_{city}.pdf " ) sp.call(make, cwd='../collaborator_report', shell=True) engine.dispose()
def polygon_fill(mymap, geo_provider, data, **kwargs): """Generalized function for overlaying filled polygons on the map Args: mymap (MapPlot): The MapPlot instance geo_provider (dict): The dictionary of keys and geometries data (dict): The dictionary of keys and values used for picking colors **kwargs (Optional): Other things needed for mapping ilabel (Optional[bool]): should values be labelled? Defaults to `False` plotmissing (bool): should geometries not included in the `data` be mapped? Defaults to `True` """ bins = kwargs.get("bins", np.arange(0, 101, 10)) cmap = stretch_cmap(kwargs.get("cmap"), bins, extend=kwargs.get("extend")) ilabel = kwargs.get("ilabel", False) norm = mpcolors.BoundaryNorm(bins, cmap.N) lblformat = kwargs.get("lblformat", "%s") labels = kwargs.get("labels", dict()) plotmissing = kwargs.get("plotmissing", True) for polykey, polydict in geo_provider.items(): # our dictionary is bytes so we need str val = data.get(polykey, None) if val is None: if not plotmissing: continue lbl = labels.get(polykey, "-") c = "white" else: lbl = labels.get(polykey, lblformat % (val, )) c = cmap(norm([val]))[0] # in python3, our dict types are byte arrays for polyi, polygon in enumerate(polydict.get("geom", [])): if polygon.exterior is None: continue a = np.asarray(polygon.exterior) for ax in mymap.axes: points = ax.projection.transform_points( ccrs.Geodetic(), a[:, 0], a[:, 1]) p = mpatches.Polygon( points[:, :2], fc=c, ec="k", zorder=reference.Z_FILL, lw=0.1, ) ax.add_patch(p) if ilabel and polyi == 0: txt = ax.text( polydict.get("lon", polygon.centroid.x), polydict.get("lat", polygon.centroid.y), lbl, zorder=100, clip_on=True, ha="center", va="center", transform=ccrs.PlateCarree(), ) txt.set_path_effects( [PathEffects.withStroke(linewidth=2, foreground="w")]) kwargs.pop("cmap", None) kwargs.pop("bins", None) mymap.draw_colorbar(bins, cmap, norm, **kwargs)
def outline_text(ax): """Add a white outline to all text to make it stand out from the background.""" effects = [patheffects.withStroke(linewidth=2, foreground='w')] for artist in ax.findobj(text.Text): artist.set_path_effects(effects)
print 'GIS Acres', info['GISACRES'] #m.plot(x, y, marker=None,color=colors[colorI],linewidth=lw) patches2.append(Polygon(np.array(shape), True) ) print "" ax.add_collection(PatchCollection(patches2, facecolor= 'maroon', alpha=.55, edgecolor='k', linewidths=1, zorder=2)) # Plot station locations lats = [44.027889,43.960083] lons = [-115.803917,-115.687] stnid = ['HFNC1','TT029'] elev = [6294,8142] # feet m.scatter(lons,lats,color='darkorange',edgecolor='k',linewidth='1',s=150,zorder=500) plt.text(lons[0],lats[0],stnid[0],zorder=500,fontdict={'weight':'bold','color':'oldlace','size':12}, path_effects=[PathEffects.withStroke(linewidth=1,foreground="k")]) plt.text(lons[1],lats[1],stnid[1],zorder=500,fontdict={'weight':'bold','color':'oldlace','size':12}, path_effects=[PathEffects.withStroke(linewidth=1,foreground="k")]) #m.scatter(-116.2146,43.6187,s=250) # Boise #plt.text(-116.2146,43.6187,'Boise') # Boise #m.scatter(-116.,44.1,color='dodgerblue',s=150) # sounding location\ 19 August 2016 1400 UTC #plt.text(-116.,44.1,'sounding 08192016') # sounding location\ 19 August 2016 1400 UTC print "finished plotting base" #------------------------------------------------------------------------------ plotted_cb = False # colorbar plotted flag fig.set_size_inches(8,10) ah = range(6,24)
def add_vals_on_map(ax, projection, var, lons, lats, minval=None, maxval=None, cmap='rainbow', shift_x=0., shift_y=0., fontsize=12, colors=True): '''Given an input projection, a variable containing the values and a plot put the values on a map exlcuing NaNs and taking care of not going outside of the map boundaries, which can happen. - minval, maxval set the extents for the colorscale cmap - shift_x and shift_y apply a shifting offset to all text labels - colors indicate whether the colorscale cmap should be used to map the values of the array''' if not minval: minval = np.nanmin(var) if not maxval: maxval = np.nanmax(var) norm = mplcolors.Normalize(vmin=minval, vmax=maxval) m = mplcm.ScalarMappable(norm=norm, cmap=cmap) if (importlib.util.find_spec("cartopy") is not None): extents = ax.get_extent() else: if projection == 'italy': extents = [6, 19.0, 36.0, 48] lon_min, lon_max, lat_min, lat_max = extents # Remove values outside of the extents and NaN # somehow np.isnan has to be used as this condition var == np.nan does not recognize # the NaN inds = np.argwhere((lon_min <= lons) & (lons <= lon_max) & (lat_min <= lats) & (lats <= lat_max) & (np.isnan(var) != True)) var = var[inds] lons = lons[inds] lats = lats[inds] for i, txt in enumerate(var): if colors: ax.annotate(('%d' % txt), (lons[i] + shift_x, lats[i] + shift_y), color=m.to_rgba(float(txt)), weight='bold', fontsize=fontsize, path_effects=[ patheffects.withStroke(linewidth=1, foreground="black") ]) else: ax.annotate(('%d' % txt), (lons[i] + shift_x, lats[i] + shift_y), color='white', weight='bold', fontsize=fontsize, path_effects=[ patheffects.withStroke(linewidth=1, foreground="black") ])
def multichannel_plot(self, stream): if self.ids: for id_ in self.ids: if not any([tr.id == id_ for tr in stream]): net, sta, loc, cha = id_.split(".") header = { 'network': net, 'station': sta, 'location': loc, 'channel': cha, 'starttime': self.start_time } data = np.zeros(2) stream.append(Trace(data=data, header=header)) stream.sort() self.figure.clear() fig = self.figure stream.plot(fig=fig, method="fast", draw=False, equal_scale=False, size=(self.args.x_size, self.args.y_size), title="", color='Blue', tick_format=self.args.tick_format, number_of_ticks=self.args.time_tick_nb) fig.subplots_adjust(left=0, right=1, top=1, bottom=0) bbox = dict(boxstyle="round", fc="w", alpha=0.8) path_effects = [withStroke(linewidth=4, foreground="w")] pad = 10 for tr, ax in zip(stream, fig.axes): ax.set_title("") ax.text(0.1, 0.9, tr.id, va="top", ha="left", transform=ax.transAxes, bbox=bbox, size=self.args.title_size) xlabels = ax.get_xticklabels() ylabels = ax.get_yticklabels() plt.setp(ylabels, ha="left", path_effects=path_effects) ax.yaxis.set_tick_params(pad=-pad) # treatment for bottom axes: if ax is fig.axes[-1]: plt.setp(xlabels, va="bottom", size=self.args.time_legend_size, bbox=bbox) plt.setp(xlabels[:1], ha="left") plt.setp(xlabels[-1:], ha="right") ax.xaxis.set_tick_params(pad=-pad) # all other axes else: plt.setp(xlabels, visible=False) locator = MaxNLocator(nbins=4, prune="both") ax.yaxis.set_major_locator(locator) ax.yaxis.grid(False) ax.grid(True, axis="x") for ax in fig.axes[::2]: ax.set_axis_bgcolor("0.8") fig.canvas.draw()
mask_outside_polygons(polys, '0.9', plt) # get lake ploygons polygons = [] for polygon in m.lakepolygons: poly = polygon.get_coords() plt.fill(poly[:, 0], poly[:, 1], '0.9') polygons.append(poly) ''' ########################################################################################### annotate cities ########################################################################################### ''' import matplotlib.patheffects as PathEffects pe = [PathEffects.withStroke(linewidth=2.5, foreground="w")] llat = [] llon = [] locs = [] textoffset = [] # read data lines = open(capfile).readlines() for line in lines: llon.append(float(line.strip().split(',')[0])) llat.append(float(line.strip().split(',')[1])) locs.append(line.strip().split(',')[2]) textoffset.append(float(line.strip().split(',')[3])) # plot locs on map
def field(gid=0, home='nfl', away='', show=False, unit='yd', zero='l'): """ Draws a football field with the teams who are participating in the game. Teams are either supplied via the home and away arguments, or by looking them up from the game_id provided by the gid argument Parameters ---------- gid: an int of a game_id for which to draw the field home: a string of the home team's code. Not necessary if a game_id is provided away: a string of the away team's code. Not necessary if a game_id is provided show: a boolean of whether or not to show the plot unit: a string for the units with which to draw the field. Default is 'yds' for yards, could be 'ft' for feet zero: a string for where the origin of the plot should be. Default is 'l', meaning lower left corner. Could be 'c' for center Returns ------- fig, ax: the figure and axes objects (respectively) """ # If a game ID is provided, get the home and away team from the provided # game ID if gid != 0: gid = check.game_id(gid) home, away = find.game_teams(gid) # If no game ID provided, and the home team is 'NFL', set home and away # to NFC and AFC respectively. Otherwise, check to make sure the teams are # legit else: home = home.upper() away = away.upper() if home == 'NFL': home = 'NFC' away = 'AFC' else: home = check.team_code(home) away = check.team_code(away) # Get the teams' color codes team_info = load.teams_data() home_info = team_info[team_info['team_code'] == home] away_info = team_info[team_info['team_code'] == away] ############################# # Get the field coordinates # ############################# sidelines, endlines, goal_lines, midline, minor_yd_lines_b, \ minor_yd_lines_t, minor_yd_lines_l, minor_yd_lines_u, major_yd_lines, \ hashes_l, hashes_u, extra_pt_mark, arrow_40_l, arrow_40_u, \ arrow_30_l, arrow_30_u, arrow_20_l, arrow_20_u, arrow_10_l, \ arrow_10_u, field_marks = load.football_field_coords() ################# # Make the plot # ################# fig, ax = plt.subplots() ax.set_aspect('equal') fig.set_size_inches(50, 22.2) ax.xaxis.set_visible(False) ax.yaxis.set_visible(False) # Set field color ax.set_facecolor('#196f0c') # Put home logo at midfield if home.lower() in ['', 'nfl', 'nfc', 'afc']: img = os.path.join('img', 'logos', 'nfl.png') else: img = os.path.join('img', 'logos', f'{home}.png') img = plt.imread(img) if unit == 'yd': ax.imshow(img, extent=[52., 68., 18.65, 34.65], zorder=10) else: ax.imshow(img, extent=[-18., 18., -18., 18.], zorder=10) # Add sidelines, goal line, and 50 yard line ax.fill(sidelines['x'], sidelines['y'], '#ffffff') ax.fill(endlines['x'], endlines['y'], '#ffffff') ax.fill(goal_lines['x'], goal_lines['y'], '#ffffff') ax.fill(midline['x'], midline['y'], '#ffffff') # Add minor yard lines and major yard lines ax.fill(minor_yd_lines_b['x'], minor_yd_lines_b['y'], '#ffffff') ax.fill(minor_yd_lines_t['x'], minor_yd_lines_t['y'], '#ffffff') ax.fill(minor_yd_lines_l['x'], minor_yd_lines_l['y'], '#ffffff') ax.fill(minor_yd_lines_u['x'], minor_yd_lines_u['y'], '#ffffff') ax.fill(major_yd_lines['x'], major_yd_lines['y'], '#ffffff') # Add hash marks and extra point markers ax.fill(hashes_l['x'], hashes_l['y'], '#ffffff') ax.fill(hashes_u['x'], hashes_u['y'], '#ffffff') ax.fill(extra_pt_mark['x'], extra_pt_mark['y'], '#ffffff') # Add the numbers to the field for i, label in field_marks.iterrows(): ax.text(x=label['x'], y=label['y'], s=label['text'], fontsize=50, color='#ffffff', fontweight='bold', rotation=label['rotation'], fontname='Impact') # Add the arrows to the field ax.fill(arrow_40_l['x'], arrow_40_l['y'], '#ffffff') ax.fill(arrow_40_u['x'], arrow_40_u['y'], '#ffffff') ax.fill(arrow_30_l['x'], arrow_30_l['y'], '#ffffff') ax.fill(arrow_30_u['x'], arrow_30_u['y'], '#ffffff') ax.fill(arrow_20_l['x'], arrow_20_l['y'], '#ffffff') ax.fill(arrow_20_u['x'], arrow_20_u['y'], '#ffffff') ax.fill(arrow_10_l['x'], arrow_10_l['y'], '#ffffff') ax.fill(arrow_10_u['x'], arrow_10_u['y'], '#ffffff') ax.text(x=5, y=26.65, s=f'{home_info.nickname.iloc[0]}', fontdict={ 'ha': 'center', 'va': 'center' }, fontsize=100, fontweight='bold', fontname='Impact', color=f'{home_info.endzone_text.iloc[0]}', rotation=90, path_effects=[ pe.withStroke(linewidth=20, foreground=f'{home_info.endzone_shadow.iloc[0]}') ]) ax.text(x=114, y=26.65, s=f'{away_info.nickname.iloc[0]}', fontdict={ 'ha': 'center', 'va': 'center' }, fontsize=100, fontweight='bold', fontname='Impact', color=f'{away_info.endzone_text.iloc[0]}', rotation=-90, path_effects=[ pe.withStroke(linewidth=20, foreground=f'{away_info.endzone_shadow.iloc[0]}') ]) if show: plt.show() return None else: return fig, ax
def play_frame(gid=0, pid=0, home='', away='', frame_no=0, plot_los=True, plot_first_down_marker=True, plot_arrows=True, prechecked_gid=False, prechecked_pid=False, prechecked_frame=False, tracking=pd.DataFrame()): """ Draw a frame of a given play. Teams are either supplied via the home and away arguments, or by looking them up from the game_id provided by the gid argument Parameters ---------- gid: an int representing the game_id pid: an int representing the play_id home: a string of the home team's code. Not necessary if a game_id is provided away: a string of the away team's code. Not necessary if a game_id is provided frame_no: the number of the frame to plot plot_los: a boolean of whether or not to plot the line of scrimmage on the plot plot_first_down_marker: a boolean of whether or not to plot the first down line on the plot prechecked_frame: a boolean indicating whether or not it's okay to skip the frame validation. Defaulting to False, but should be set to True when using the draw_play_gif() function tracking: a dataframe of tracking data that can be used to speed up plotting Returns ------- fig, ax: the figure and axes objects (respectively) """ if gid != 0: # Start by checking the game ID if it is provided but not yet checked if not prechecked_gid: gid = check.game_id(gid) prechecked_gid = True # Get the home and away teams for the game home, away = find.game_teams(gid) # If no game ID provided, and the home team is 'NFL', set home and away # to NFC and AFC respectively. Otherwise, check to make sure the teams are # legit else: home = home.upper() away = away.upper() if home == 'NFL': home = 'NFC' away = 'AFC' else: home = check.team_code(home) away = check.team_code(away) gid = find.game_id(home, away) # Next, check the play ID if it has not already been checked if not prechecked_pid: pid = check.play_id(gid, pid, prechecked_gid) prechecked_pid = True # If tracking isn't supplied, load all relevant tracking data if tracking.empty: tracking = merge.tracking_and_plays(gid, pid) if not prechecked_frame: frame_no = check.frame_no(gid, pid, frame_no, tracking) # Start prepping the data for the plot. Primarily, the jersey numbers' # rotation angle based on team and play direction tracking['jersey_num_orientation'] = orient_jersey_num( gid, pid, prechecked_gid, prechecked_pid, tracking) # Split the frame's data into the home team, the away team, and the ball's # data (respectively) home_frame = tracking[(tracking['team'] == 'home') & (tracking['frame_id'] == frame_no)] away_frame = tracking[(tracking['team'] == 'away') & (tracking['frame_id'] == frame_no)] ball_frame = tracking[(tracking['team'] == 'football') & (tracking['frame_id'] == frame_no)] # Get the hex color information about each team to use to make the plot teams_info = load.teams_data() home_info = teams_info[teams_info['team_code'] == home] away_info = teams_info[teams_info['team_code'] == away] home_uni_base = home_info['home_uni_base'].iloc[0] home_uni_highlight = home_info['home_uni_highlight'].iloc[0] home_uni_number = home_info['home_uni_number'].iloc[0] home_uni_number_highlight = home_info['home_uni_number_highlight'].iloc[0] away_uni_base = away_info['away_uni_base'].iloc[0] away_uni_highlight = away_info['away_uni_highlight'].iloc[0] away_uni_number = away_info['away_uni_number'].iloc[0] away_uni_number_highlight = away_info['away_uni_number_highlight'].iloc[0] # If the line of scrimmage is to be plotted, determine its position if plot_los: los = find.line_of_scrimmage(gid, pid) los = pd.DataFrame({ 'x': [ los - (2 / 12), los + (2 / 12), los + (2 / 12), los - (2 / 12), los - (2 / 12) ], 'y': [1 / 9, 1 / 9, 53 + (2 / 9), 53 + (2 / 9), 1 / 9] }) # If the first down line is to be plotted, determine its position if plot_first_down_marker: first_down = find.first_down_line(gid, pid, tracking, prechecked_gid, prechecked_pid) first_down_line = pd.DataFrame({ 'x': [ first_down - (2 / 12), first_down + (2 / 12), first_down + (2 / 12), first_down - (2 / 12), first_down - (2 / 12) ], 'y': [1 / 9, 1 / 9, 53 + (2 / 9), 53 + (2 / 9), 1 / 9] }) # Draw the field fig, ax = field(gid) # Plot the home team's players home_frame.plot(x='player_x', y='player_y', kind='scatter', ax=ax, color=home_uni_base, s=800, edgecolor=home_uni_highlight, linewidth=2, zorder=15) # Add the jersey numbers for the home team for i, player in home_frame.iterrows(): ax.text( x=player['player_x'], y=player['player_y'], s=str(int(player['player_no'])), fontsize=15, color=home_uni_number, path_effects=[ pe.withStroke(linewidth=3, foreground=home_uni_number_highlight) ], fontweight='bold', rotation=player['jersey_num_orientation'], zorder=20, fontdict={ 'ha': 'center', 'va': 'center' }, ) if plot_arrows: ax.arrow(x=player['player_x'], y=player['player_y'], dx=3 * math.cos(player['player_orientation']), dy=3 * math.sin(player['player_orientation']), length_includes_head=True, width=0.3, color=home_uni_highlight, zorder=14) # Plot the away team's players away_frame.plot('player_x', 'player_y', kind='scatter', ax=ax, color=away_uni_base, s=800, edgecolor=away_uni_highlight, linewidth=2, zorder=15) # Add the jersey numbers for the away team for i, player in away_frame.iterrows(): ax.text( x=player['player_x'], y=player['player_y'], s=str(int(player['player_no'])), fontsize=15, color=away_uni_number, path_effects=[ pe.withStroke(linewidth=3, foreground=away_uni_number_highlight) ], fontweight='bold', rotation=player['jersey_num_orientation'], zorder=20, fontdict={ 'ha': 'center', 'va': 'center' }, ) if plot_arrows: ax.arrow(x=player['player_x'], y=player['player_y'], dx=3 * math.cos(player['player_orientation']), dy=3 * math.sin(player['player_orientation']), length_includes_head=True, width=0.3, color=away_uni_highlight, zorder=14) # Plot the ball ball_frame.plot('player_x', 'player_y', kind='scatter', ax=ax, color='#624a2e', s=100, edgecolor='#000000', linewidth=2, zorder=15) ax.fill(los['x'], los['y'], '#183ec1') ax.fill(first_down_line['x'], first_down_line['y'], '#ffcb05') return fig, ax
import matplotlib.pyplot as plt import matplotlib.patheffects as PathEffects import numpy years = numpy.array( years ) (fig, ax) = plt.subplots(1,1) bars = ax.bar( numpy.arange(1,60)-0.4, 2013.0 - years) last = None for i, yr in enumerate(years): if yr != last: x = i if i == 0: x = -2.5 text = ax.text( x+1, 2013 - yr + 0.5, "%.0f" % (yr,), ha='left', va='bottom') text.set_path_effects([PathEffects.withStroke(linewidth=2, foreground="yellow")]) last = yr ax.set_yticks( range(3,63,10) ) ax.set_yticklabels( range(2010,1940,-10) ) ax.set_title("2013 Ames Average Temperature Coldest Period Since") ax.set_xlabel("Period of Days prior to 2 April") ax.set_ylabel("Previous Year Colder than 2013") ax.grid(True) fig.savefig('test.png')
data['eigen_vectors'], data['principal_angle'], data['area_px']): figure.gca().scatter(center[1], center[0], color='k', s=0) for val, vec in zip(vals, vecs): figure.gca().plot([ center[1] + tensor_factor * val * vec[1], center[1] - tensor_factor * val * vec[1] ], [ center[0] - tensor_factor * val * vec[0], center[0] + tensor_factor * val * vec[0] ], color='r', linewidth=2, path_effects=[ patheffects.withStroke( linewidth=4, foreground='w') ]) """ Saves an overlay of the inverted image with the detected labelled regions and the cell separation orientations.""" figure.savefig(imgpath[:-4] + "_inv_sep_orientations.pdf", dpi=300) """ Makes and saves a polar histogram of cracks orientations.""" figure = plt.figure(img_file + "_hist") figure.clf() figure.patch.set_facecolor('w') figure.set_size_inches(5, 5) ax = figure.add_subplot(111, polar=True) colormap = 'plasma' n_bins = 36
def embedding( adata: AnnData, basis: str, *, color: Union[str, Sequence[str], None] = None, gene_symbols: Optional[str] = None, use_raw: Optional[bool] = None, sort_order: bool = True, edges: bool = False, edges_width: float = 0.1, edges_color: Union[str, Sequence[float], Sequence[str]] = 'grey', neighbors_key: Optional[str] = None, arrows: bool = False, arrows_kwds: Optional[Mapping[str, Any]] = None, groups: Optional[str] = None, components: Union[str, Sequence[str]] = None, layer: Optional[str] = None, projection: Literal['2d', '3d'] = '2d', scale_factor: Optional[float] = None, color_map: Union[Colormap, str, None] = None, cmap: Union[Colormap, str, None] = None, palette: Union[str, Sequence[str], Cycler, None] = None, na_color: ColorLike = "lightgray", na_in_legend: bool = True, size: Union[float, Sequence[float], None] = None, frameon: Optional[bool] = None, legend_fontsize: Union[int, float, _FontSize, None] = None, legend_fontweight: Union[int, _FontWeight] = 'bold', legend_loc: str = 'right margin', legend_fontoutline: Optional[int] = None, vmax: Union[VMinMax, Sequence[VMinMax], None] = None, vmin: Union[VMinMax, Sequence[VMinMax], None] = None, add_outline: Optional[bool] = False, outline_width: Tuple[float, float] = (0.3, 0.05), outline_color: Tuple[str, str] = ('black', 'white'), ncols: int = 4, hspace: float = 0.25, wspace: Optional[float] = None, title: Union[str, Sequence[str], None] = None, show: Optional[bool] = None, save: Union[bool, str, None] = None, ax: Optional[Axes] = None, return_fig: Optional[bool] = None, **kwargs, ) -> Union[Figure, Axes, None]: """\ Scatter plot for user specified embedding basis (e.g. umap, pca, etc) Parameters ---------- basis Name of the `obsm` basis to use. {adata_color_etc} {edges_arrows} {scatter_bulk} {show_save_ax} Returns ------- If `show==False` a :class:`~matplotlib.axes.Axes` or a list of it. """ check_projection(projection) sanitize_anndata(adata) # Setting up color map for continuous values if color_map is not None: if cmap is not None: raise ValueError("Cannot specify both `color_map` and `cmap`.") else: cmap = color_map cmap = copy(get_cmap(cmap)) cmap.set_bad(na_color) kwargs["cmap"] = cmap # Prevents warnings during legend creation na_color = colors.to_hex(na_color, keep_alpha=True) if size is not None: kwargs['s'] = size if 'edgecolor' not in kwargs: # by default turn off edge color. Otherwise, for # very small sizes the edge will not reduce its size # (https://github.com/theislab/scanpy/issues/293) kwargs['edgecolor'] = 'none' if groups: if isinstance(groups, str): groups = [groups] args_3d = dict(projection='3d') if projection == '3d' else {} # Deal with Raw if use_raw is None: # check if adata.raw is set use_raw = layer is None and adata.raw is not None if use_raw and layer is not None: raise ValueError( "Cannot use both a layer and the raw representation. Was passed:" f"use_raw={use_raw}, layer={layer}.") if wspace is None: # try to set a wspace that is not too large or too small given the # current figure size wspace = 0.75 / rcParams['figure.figsize'][0] + 0.02 if adata.raw is None and use_raw: raise ValueError( "`use_raw` is set to True but AnnData object does not have raw. " "Please check.") # turn color into a python list color = [color] if isinstance(color, str) or color is None else list(color) if title is not None: # turn title into a python list if not None title = [title] if isinstance(title, str) else list(title) # get the points position and the components list # (only if components is not None) data_points, components_list = _get_data_points(adata, basis, projection, components, scale_factor) # Setup layout. # Most of the code is for the case when multiple plots are required # 'color' is a list of names that want to be plotted. # Eg. ['Gene1', 'louvain', 'Gene2']. # component_list is a list of components [[0,1], [1,2]] if (not isinstance(color, str) and isinstance(color, cabc.Sequence) and len(color) > 1) or len(components_list) > 1: if ax is not None: raise ValueError( "Cannot specify `ax` when plotting multiple panels " "(each for a given value of 'color').") if len(components_list) == 0: components_list = [None] # each plot needs to be its own panel num_panels = len(color) * len(components_list) fig, grid = _panel_grid(hspace, wspace, ncols, num_panels) else: if len(components_list) == 0: components_list = [None] grid = None if ax is None: fig = pl.figure() ax = fig.add_subplot(111, **args_3d) # turn vmax and vmin into a sequence if isinstance(vmax, str) or not isinstance(vmax, cabc.Sequence): vmax = [vmax] if isinstance(vmin, str) or not isinstance(vmin, cabc.Sequence): vmin = [vmin] if 's' in kwargs: size = kwargs.pop('s') if size is not None: # check if size is any type of sequence, and if so # set as ndarray import pandas.core.series if (size is not None and isinstance( size, (cabc.Sequence, pandas.core.series.Series, np.ndarray)) and len(size) == adata.shape[0]): size = np.array(size, dtype=float) else: size = 120000 / adata.shape[0] ### # make the plots axs = [] import itertools idx_components = range(len(components_list)) # use itertools.product to make a plot for each color and for each component # For example if color=[gene1, gene2] and components=['1,2, '2,3']. # The plots are: [ # color=gene1, components=[1,2], color=gene1, components=[2,3], # color=gene2, components = [1, 2], color=gene2, components=[2,3], # ] for count, (value_to_plot, component_idx) in enumerate( itertools.product(color, idx_components)): color_source_vector = _get_color_source_vector( adata, value_to_plot, layer=layer, use_raw=use_raw, gene_symbols=gene_symbols, groups=groups, ) color_vector, categorical = _color_vector( adata, value_to_plot, color_source_vector, palette=palette, na_color=na_color, ) ### Order points order = slice(None) if sort_order is True and value_to_plot is not None and categorical is False: # Higher values plotted on top, null values on bottom order = np.argsort(-color_vector, kind="stable")[::-1] elif sort_order and categorical: # Null points go on bottom order = np.argsort(~pd.isnull(color_source_vector), kind="stable") # Set orders if isinstance(size, np.ndarray): size = np.array(size)[order] color_source_vector = color_source_vector[order] color_vector = color_vector[order] _data_points = data_points[component_idx][order, :] # if plotting multiple panels, get the ax from the grid spec # else use the ax value (either user given or created previously) if grid: ax = pl.subplot(grid[count], **args_3d) axs.append(ax) if not (settings._frameon if frameon is None else frameon): ax.axis('off') if title is None: if value_to_plot is not None: ax.set_title(value_to_plot) else: ax.set_title('') else: try: ax.set_title(title[count]) except IndexError: logg.warning( "The title list is shorter than the number of panels. " "Using 'color' value instead for some plots.") ax.set_title(value_to_plot) # check vmin and vmax options if categorical: kwargs['vmin'] = kwargs['vmax'] = None else: kwargs['vmin'], kwargs['vmax'] = _get_vmin_vmax( vmin, vmax, count, color_vector) # make the scatter plot if projection == '3d': cax = ax.scatter( _data_points[:, 0], _data_points[:, 1], _data_points[:, 2], marker=".", c=color_vector, rasterized=settings._vector_friendly, **kwargs, ) else: scatter = ( partial(ax.scatter, s=size, plotnonfinite=True) if scale_factor is None else partial( circles, s=size, ax=ax) # size in circles is radius ) if add_outline: # the default outline is a black edge followed by a # thin white edged added around connected clusters. # To add an outline # three overlapping scatter plots are drawn: # First black dots with slightly larger size, # then, white dots a bit smaller, but still larger # than the final dots. Then the final dots are drawn # with some transparency. bg_width, gap_width = outline_width point = np.sqrt(size) gap_size = (point + (point * gap_width) * 2)**2 bg_size = (np.sqrt(gap_size) + (point * bg_width) * 2)**2 # the default black and white colors can be changes using # the contour_config parameter bg_color, gap_color = outline_color # remove edge from kwargs if present # because edge needs to be set to None kwargs['edgecolor'] = 'none' # remove alpha for outline alpha = kwargs.pop('alpha') if 'alpha' in kwargs else None ax.scatter( _data_points[:, 0], _data_points[:, 1], s=bg_size, marker=".", c=bg_color, rasterized=settings._vector_friendly, **kwargs, ) ax.scatter( _data_points[:, 0], _data_points[:, 1], s=gap_size, marker=".", c=gap_color, rasterized=settings._vector_friendly, **kwargs, ) # if user did not set alpha, set alpha to 0.7 kwargs['alpha'] = 0.7 if alpha is None else alpha cax = scatter( _data_points[:, 0], _data_points[:, 1], marker=".", c=color_vector, rasterized=settings._vector_friendly, **kwargs, ) # remove y and x ticks ax.set_yticks([]) ax.set_xticks([]) if projection == '3d': ax.set_zticks([]) # set default axis_labels name = _basis2name(basis) if components is not None: axis_labels = [ name + str(x + 1) for x in components_list[component_idx] ] elif projection == '3d': axis_labels = [name + str(x + 1) for x in range(3)] else: axis_labels = [name + str(x + 1) for x in range(2)] ax.set_xlabel(axis_labels[0]) ax.set_ylabel(axis_labels[1]) if projection == '3d': # shift the label closer to the axis ax.set_zlabel(axis_labels[2], labelpad=-7) ax.autoscale_view() if edges: _utils.plot_edges(ax, adata, basis, edges_width, edges_color, neighbors_key) if arrows: _utils.plot_arrows(ax, adata, basis, arrows_kwds) if value_to_plot is None: # if only dots were plotted without an associated value # there is not need to plot a legend or a colorbar continue if legend_fontoutline is not None: path_effect = [ patheffects.withStroke(linewidth=legend_fontoutline, foreground='w') ] else: path_effect = None # Adding legends if categorical: _add_categorical_legend( ax, color_source_vector, palette=_get_palette(adata, value_to_plot), scatter_array=_data_points, legend_loc=legend_loc, legend_fontweight=legend_fontweight, legend_fontsize=legend_fontsize, legend_fontoutline=path_effect, na_color=na_color, na_in_legend=na_in_legend, multi_panel=bool(grid), ) else: # TODO: na_in_legend should have some effect here pl.colorbar(cax, ax=ax, pad=0.01, fraction=0.08, aspect=30) if return_fig is True: return fig axs = axs if grid else ax _utils.savefig_or_show(basis, show=show, save=save) if show is False: return axs
cs_fig = sewershed_cso_rain.plot(ax=ax, column='rain_height', edgecolor='black', cmap='Blues', cax=cax, legend=True, legend_kwds={ 'label': "Population by Country", 'orientation': "horizontal" }) # Label each polygon with the height of rain that can be handled in inches sewershed_cso_rain.apply(lambda x: cs_fig.annotate( s='{:.4f} in'.format(x['rain_height']), xy=x.geometry.centroid.coords[0], ha='center', color='black', path_effects=[pe.withStroke(linewidth=4, foreground="white")]), axis=1) # Label sewershed with name # sewershed_cso_rain.apply(lambda x: ss_fig.annotate(s=x['Sewershed'], # xy=x.geometry.centroid.coords[0], # ha='center', # color='black', # path_effects=[pe.withStroke(linewidth=4, foreground="white")]), # axis=1) # Display figure plt.show()
def main(): cwd = os.getcwd() cycles_book = open_workbook('campbell_output.xls') dssat_book = open_workbook('DSSAT_output.xls') apsim_book = open_workbook('APSIM_output.xls') feddes_book = open_workbook('feddes_output.xls') epic_book = open_workbook('epic_output.xls') wofost_book = open_workbook('wofost_output.xls') cycles_soil = cycles_book.sheet_by_name('soil') dssat_soil = dssat_book.sheet_by_name('soil') apsim_soil = apsim_book.sheet_by_name('soil') feddes_soil = feddes_book.sheet_by_name('soil') epic_soil = epic_book.sheet_by_name('soil') wofost_soil = wofost_book.sheet_by_name('soil') water_content_colmns = [7, 8, 9, 10, 11, 12, 13, 14, 15, 16] water_potential_colmns = [17, 18, 19, 20, 21, 22, 23, 24, 25, 26] nrows = cycles_soil.nrows water_content_cycles = np.zeros([nrows, len(water_content_colmns)]) water_content_dssat = np.zeros([nrows, len(water_content_colmns)]) water_content_apsim = np.zeros([nrows, len(water_content_colmns)]) water_content_feddes = np.zeros([nrows, len(water_content_colmns)]) water_content_epic = np.zeros([nrows, len(water_content_colmns)]) water_content_wofost = np.zeros([nrows, len(water_content_colmns)]) water_potential_cycles = np.zeros([nrows, len(water_potential_colmns)]) water_potential_dssat = np.zeros([nrows, len(water_potential_colmns)]) water_potential_apsim = np.zeros([nrows, len(water_potential_colmns)]) water_potential_feddes = np.zeros([nrows, len(water_potential_colmns)]) water_potential_epic = np.zeros([nrows, len(water_potential_colmns)]) water_potential_wofost = np.zeros([nrows, len(water_potential_colmns)]) for i, row in enumerate(range(1, nrows)): for j, col in enumerate(water_content_colmns): water_content_cycles[i, j] = cycles_soil.cell(row, col).value water_content_dssat[i, j] = dssat_soil.cell(row, col).value water_content_apsim[i, j] = apsim_soil.cell(row, col).value water_content_feddes[i, j] = feddes_soil.cell(row, col).value water_content_epic[i, j] = epic_soil.cell(row, col).value water_content_wofost[i, j] = wofost_soil.cell(row, col).value for i, row in enumerate(range(1, nrows)): for j, col in enumerate(water_potential_colmns): water_potential_cycles[i, j] = cycles_soil.cell(row, col).value water_potential_dssat[i, j] = dssat_soil.cell(row, col).value water_potential_apsim[i, j] = apsim_soil.cell(row, col).value water_potential_feddes[i, j] = feddes_soil.cell(row, col).value water_potential_epic[i, j] = epic_soil.cell(row, col).value water_potential_wofost[i, j] = wofost_soil.cell(row, col).value # Plots depths = [0.05, 0.15, 0.25, 0.35, 0.45, 0.55, 0.65, 0.75, 0.85, 0.95] # Selected days based on Campbells silt loam: mid-way between start and # start drop, start drop, and half between start drop and end sim_days = [15, 30, 45] # Water potential plt.figure(1, figsize=(18, 12)) plt.subplot(2, 3, 2).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_potential_cycles[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_potential_cycles[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_potential_cycles[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([-2200, 0]) #plt.xlabel("Water potential (J/kg)") #plt.ylabel("Soil depth (m)", fontsize=14, labelpad=8) plt.text(-2110, 0.2, 'CropSyst', path_effects=[pe.withStroke(linewidth=10, foreground='w')], bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) #plt.legend(loc='lower left') plt.subplot(2, 3, 3).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_potential_dssat[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_potential_dssat[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_potential_dssat[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([-2200, 0]) #plt.xlabel(r"Water potential (J kg$^{-1}$)", fontsize=22, labelpad=8) #plt.ylabel("Soil depth (m)") plt.text(-2110, 0.2, 'DSSAT', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) plt.subplot(2, 3, 1).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_potential_apsim[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_potential_apsim[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_potential_apsim[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([-2200, 0]) #plt.xlabel(r"Water potential (J kg$^{-1}$)", fontsize=22, labelpad=8) plt.ylabel("Soil depth (m)", fontsize=22, labelpad=8) plt.text(-2110, 0.2, 'APSIM', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) plt.legend(loc='lower left', prop={'size': 18}) plt.subplot(2, 3, 5).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_potential_feddes[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_potential_feddes[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_potential_feddes[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([-2200, 0]) plt.xlabel(r"Water potential (J kg$^{-1}$)", fontsize=22, labelpad=8) #plt.ylabel("Soil depth (m)", fontsize=22, labelpad=8) plt.text(-2110, 0.2, 'SWAP', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) #plt.legend() plt.subplot(2, 3, 6).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_potential_wofost[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_potential_wofost[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_potential_wofost[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([-2200, 0]) plt.xlabel(r"Water potential (J kg$^{-1}$)", fontsize=22, labelpad=8) #plt.ylabel("Soil depth (m)", fontsize=22, labelpad=8) plt.text(-2110, 0.2, 'WOFOST', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) plt.subplot(2, 3, 4).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_potential_epic[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_potential_epic[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_potential_epic[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([-2200, 0]) plt.xlabel(r"Water potential (J kg$^{-1}$)", fontsize=22, labelpad=8) plt.ylabel("Soil depth (m)", fontsize=22, labelpad=8) plt.text(-2110, 0.2, 'EPIC', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) plt.setp(plt.subplot(2, 3, 1).get_xticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 2).get_xticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 2).get_yticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 3).get_yticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 5).get_yticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 6).get_yticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 3).get_xticklabels(), visible=False) plt.subplots_adjust(wspace=0.08, hspace=0.05, right=0.9) plt.savefig('Fig4_WP.svg') # Water content plt.figure(2, figsize=(18, 12)) plt.subplot(2, 3, 2).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_content_cycles[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_content_cycles[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_content_cycles[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([0.05, 0.39]) #plt.xlabel("Water content (m3/m3)") #plt.ylabel("Soil depth (m)", fontsize=16, labelpad=8) plt.text(0.28, 0.2, 'CropSyst', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) #plt.legend() plt.subplot(2, 3, 3).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_content_dssat[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_content_dssat[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_content_dssat[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([0.05, 0.39]) #plt.xlabel(r"Water content (m$^{3}$ m$^{-3}$)", fontsize=22, labelpad=8) #plt.ylabel("Soil depth (m)") plt.text(0.28, 0.2, 'DSSAT', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) #plt.legend() plt.subplot(2, 3, 1).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_content_apsim[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_content_apsim[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_content_apsim[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([0.05, 0.39]) #plt.xlabel(r"Water content (m$^{3}$ m$^{-3}$)", fontsize=22, labelpad=8) plt.ylabel("Soil depth (m)", fontsize=22, labelpad=8) plt.text(0.28, 0.2, 'APSIM', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) plt.legend(loc='lower right', prop={'size': 18}) plt.subplot(2, 3, 5).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_content_feddes[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_content_feddes[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_content_feddes[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([0.05, 0.39]) plt.xlabel(r"Water content (m$^{3}$ m$^{-3}$)", fontsize=22, labelpad=8) #plt.ylabel("Soil depth (m)", fontsize=22, labelpad=8) plt.text(0.28, 0.2, 'SWAP', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) #plt.legend() plt.subplot(2, 3, 4).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_content_epic[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_content_epic[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_content_epic[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([0.05, 0.39]) plt.xlabel(r"Water content (m$^{-3}$ m$^{-3}$)", fontsize=22, labelpad=8) plt.ylabel("Soil depth (m)", fontsize=22, labelpad=8) #plt.legend() plt.text(0.28, 0.2, 'EPIC', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) plt.subplot(2, 3, 6).tick_params(axis='both', which='major', labelsize=16) plt.plot(water_content_wofost[sim_days[0]], depths, color='k', marker=".", dashes=(None, None), label='Day %d' % sim_days[0]) plt.plot(water_content_wofost[sim_days[1]], depths, color='k', marker=".", dashes=[5, 5], label='Day %d' % sim_days[1]) plt.plot(water_content_wofost[sim_days[2]], depths, color='k', marker=".", dashes=[5, 3, 1, 3], label='Day %d' % sim_days[2]) plt.ylim([0.95, 0.05]) plt.xlim([0.05, 0.39]) plt.xlabel(r"Water content (m$^{-3}$ m$^{-3}$)", fontsize=22, labelpad=8) #plt.ylabel("Soil depth (m)", fontsize=22, labelpad=8) #plt.legend() plt.text(0.28, 0.2, 'WOFOST', bbox={ 'facecolor': 'white', 'alpha': 0, 'pad': 10 }, fontsize=22) plt.setp(plt.subplot(2, 3, 1).get_xticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 2).get_xticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 2).get_yticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 3).get_yticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 5).get_yticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 6).get_yticklabels(), visible=False) plt.setp(plt.subplot(2, 3, 3).get_xticklabels(), visible=False) plt.subplots_adjust(wspace=0.08, hspace=0.05, right=0.9) plt.savefig('Fig3_WC.svg') plt.show()
def _plot_basemap_into_axes(ax, lons, lats, size, color, bmap=None, labels=None, projection='global', resolution='l', continent_fill_color='0.8', water_fill_color='1.0', colormap=None, marker="o", title=None, adjust_aspect_to_colorbar=False, **kwargs): # @UnusedVariable """ Creates a (or adds to existing) basemap plot with a data point scatter plot in given axes. See :func:`plot_basemap` for details on most args/kwargs. :type ax: :class:`matplotlib.axes.Axes` :param ax: Existing matplotlib axes instance, optionally with previous basemap plot (see `bmap` kwarg). :type bmap: :class:`mpl_toolkits.basemap.Basemap` :param bmap: Basemap instance in provided matplotlib Axes `ax` to reuse. If specified, any kwargs regarding the basemap plot setup will be ignored (i.e. `projection`, `resolution`, `continent_fill_color`, `water_fill_color`). :rtype: :class:`matplotlib.collections.PathCollection` :returns: Matplotlib path collection (e.g. to reuse for colorbars). """ fig = ax.figure if bmap is None: if projection == 'global': bmap = Basemap(projection='moll', lon_0=round(np.mean(lons), 4), resolution=_BASEMAP_RESOLUTIONS[resolution], ax=ax) elif projection == 'ortho': bmap = Basemap(projection='ortho', resolution=_BASEMAP_RESOLUTIONS[resolution], area_thresh=1000.0, lat_0=round(np.mean(lats), 4), lon_0=round(mean_longitude(lons), 4), ax=ax) elif projection == 'local': if min(lons) < -150 and max(lons) > 150: max_lons = max(np.array(lons) % 360) min_lons = min(np.array(lons) % 360) else: max_lons = max(lons) min_lons = min(lons) lat_0 = max(lats) / 2. + min(lats) / 2. lon_0 = max_lons / 2. + min_lons / 2. if lon_0 > 180: lon_0 -= 360 deg2m_lat = 2 * np.pi * 6371 * 1000 / 360 deg2m_lon = deg2m_lat * np.cos(lat_0 / 180 * np.pi) if len(lats) > 1: height = (max(lats) - min(lats)) * deg2m_lat width = (max_lons - min_lons) * deg2m_lon margin = 0.2 * (width + height) height += margin width += margin else: height = 2.0 * deg2m_lat width = 5.0 * deg2m_lon # do intelligent aspect calculation for local projection # adjust to figure dimensions w, h = fig.get_size_inches() ax_bbox = ax.get_position() aspect = (w * ax_bbox.width) / (h * ax_bbox.height) if adjust_aspect_to_colorbar: aspect *= 1.2 if width / height < aspect: width = height * aspect else: height = width / aspect bmap = Basemap(projection='aea', resolution=_BASEMAP_RESOLUTIONS[resolution], area_thresh=1000.0, lat_0=round(lat_0, 4), lon_0=round(lon_0, 4), width=width, height=height, ax=ax) # not most elegant way to calculate some round lats/lons def linspace2(val1, val2, n): """ returns around n 'nice' values between val1 and val2 """ dval = val2 - val1 round_pos = int(round(-np.log10(1. * dval / n))) # Fake negative rounding as not supported by future as of now. if round_pos < 0: factor = 10**(abs(round_pos)) delta = round(2. * dval / n / factor) * factor / 2 else: delta = round(2. * dval / n, round_pos) / 2 new_val1 = np.ceil(val1 / delta) * delta new_val2 = np.floor(val2 / delta) * delta n = int((new_val2 - new_val1) / delta + 1) return np.linspace(new_val1, new_val2, n) n_1 = int(np.ceil(height / max(width, height) * 8)) n_2 = int(np.ceil(width / max(width, height) * 8)) parallels = linspace2(lat_0 - height / 2 / deg2m_lat, lat_0 + height / 2 / deg2m_lat, n_1) # Old basemap versions have problems with non-integer parallels. try: bmap.drawparallels(parallels, labels=[0, 1, 1, 0]) except KeyError: parallels = sorted(list(set(map(int, parallels)))) bmap.drawparallels(parallels, labels=[0, 1, 1, 0]) if min(lons) < -150 and max(lons) > 150: lon_0 %= 360 meridians = linspace2(lon_0 - width / 2 / deg2m_lon, lon_0 + width / 2 / deg2m_lon, n_2) meridians[meridians > 180] -= 360 bmap.drawmeridians(meridians, labels=[1, 0, 0, 1]) else: msg = "Projection '%s' not supported." % projection raise ValueError(msg) # draw coast lines, country boundaries, fill continents. if MATPLOTLIB_VERSION >= [2, 0, 0]: ax.set_facecolor(water_fill_color) else: ax.set_axis_bgcolor(water_fill_color) bmap.drawcoastlines(color="0.4") bmap.drawcountries(color="0.75") bmap.fillcontinents(color=continent_fill_color, lake_color=water_fill_color) # draw the edge of the bmap projection region (the projection limb) bmap.drawmapboundary(fill_color=water_fill_color) # draw lat/lon grid lines every 30 degrees. bmap.drawmeridians(np.arange(-180, 180, 30)) bmap.drawparallels(np.arange(-90, 90, 30)) fig.bmap = bmap # compute the native bmap projection coordinates for events. x, y = bmap(lons, lats) # plot labels if labels: if 100 > len(lons) > 1: for name, xpt, ypt, _colorpt in zip(labels, x, y, color): # Check if the point can actually be seen with the current bmap # projection. The bmap object will set the coordinates to very # large values if it cannot project a point. if xpt > 1e25: continue ax.text(xpt, ypt, name, weight="heavy", color="k", zorder=100, path_effects=[ PathEffects.withStroke(linewidth=3, foreground="white") ]) elif len(lons) == 1: ax.text(x[0], y[0], labels[0], weight="heavy", color="k", path_effects=[ PathEffects.withStroke(linewidth=3, foreground="white") ]) # scatter plot is removing valid x/y points with invalid color value, # so we plot those points separately. try: nan_points = np.isnan(np.array(color, dtype=np.float)) except ValueError: # `color' was not a list of values, but a list of colors. pass else: if nan_points.any(): x_ = np.array(x)[nan_points] y_ = np.array(y)[nan_points] size_ = np.array(size)[nan_points] bmap.scatter(x_, y_, marker=marker, s=size_, c="0.3", zorder=10, cmap=None) scatter = bmap.scatter(x, y, marker=marker, s=size, c=color, zorder=10, cmap=colormap) if title: ax.set_title(title) return scatter
def fill_axis(self, ax, text): """Docstring.""" # Plot image as a colour map cmap = ax.imshow(self.im, extent=self.extent, vmin=np.min(self.im), vmax=np.max(self.im), cmap=colormaps.jesse_reds) if self.rms: # Set contour levels cont_levs = np.arange(3, 100, 3) * self.rms # add residual contours if resdiual exists; otherwise, add image contours try: ax.contour(self.resid, levels=cont_levs, colors='k', linewidths=0.75, linestyles='solid') ax.contour(self.resid, levels=-1 * np.flip(cont_levs, axis=0), colors='k', linewidths=0.75, linestyles='dashed') except AttributeError: ax.contour(self.ra_offset, self.dec_offset, self.im, colors='k', levels=cont_levs, linewidths=0.75, linestyles='solid') ax.contour(self.ra_offset, self.dec_offset, self.im, levels=-1 * np.flip(cont_levs, axis=0), colors='k', linewidths=0.75, linestyles='dashed') # Create the colorbar divider = make_axes_locatable(ax) cax = divider.append_axes("top", size="8%", pad=0.0) cbar = self.fig.colorbar(cmap, ax=ax, cax=cax, orientation='horizontal') cbar.ax.xaxis.set_tick_params(direction='out', length=3, which='major', bottom='off', top='on', labelsize=8, pad=-2, labeltop='on', labelbottom='off') cbar.ax.xaxis.set_tick_params(direction='out', length=2, which='minor', bottom='off', top='on') if np.max(self.im) > 500: tickmaj = 200 tickmin = 50 elif np.max(self.im) > 200: tickmaj = 100 tickmin = 25 elif np.max(self.im) > 100: tickmaj = 50 tickmin = 10 elif np.max(self.im) <= 100: tickmaj = 20 tickmin = 5 minorLocator = AutoMinorLocator(tickmaj / tickmin) cbar.ax.xaxis.set_minor_locator(minorLocator) cbar.ax.set_xticklabels(cbar.ax.get_xticklabels(), rotation=45, fontsize=18) cbar.set_ticks(np.arange(-10 * tickmaj, 10 * tickmaj, tickmaj)) # Colorbar label cbar.ax.text( 0.425, 0.320, r'$\mu Jy / beam$', fontsize=12, path_effects=[PathEffects.withStroke(linewidth=2, foreground="w")]) # Overplot the beam ellipse try: beam_ellipse_color = 'k' bmin = self.head['bmin'] * 3600. bmaj = self.head['bmaj'] * 3600. bpa = self.head['bpa'] el = Ellipse(xy=[4.2, -4.2], width=bmin, height=bmaj, angle=-bpa, edgecolor='k', hatch='///', facecolor='none', zorder=10) ax.add_artist(el) except KeyError: pass # Plot the scale bar if np.where(self.axes == ax)[1][0] == 0: # if first plot x = -3.015 y = -4.7 ax.plot([x, x - 10 / 9.725], [y, y], '-', linewidth=2, color='k') ax.text(x + 0.32, y + 0.15, "10 au", fontsize=18, path_effects=[ PathEffects.withStroke(linewidth=2, foreground="w") ]) # Plot a cross at the source position # ax.plot([0.0], [0.0], '+', markersize=6, markeredgewidth=1, color='w') # Add figure text if text is not None: for t in text: ax.text(*t, fontsize=18, path_effects=[ PathEffects.withStroke(linewidth=3, foreground="w") ]) if self.title: plt.suptitle(self.title)
def plot_files(dss, **args): # Using args we don't have to change the prototype function if we want to add other parameters! first = True for time_sel in dss.time: data = dss.sel(time=time_sel) data['t'].metpy.convert_units('degC') time, run, cum_hour = get_time_run_cum(data) # Build the name of the output image filename = subfolder_images[ projection] + '/' + variable_name + '_%s.png' % cum_hour cs = args['ax'].contourf(args['x'], args['y'], data['t'], extend='both', cmap=args['cmap'], levels=args['levels_temp']) css = args['ax'].contour(args['x'], args['y'], data['t'], colors='gray', levels=np.arange(-32., 34., 4.), linestyles='solid', linewidths=0.3) css.collections[8].set_linewidth(1.5) c = args['ax'].contour(args['x'], args['y'], data['gh'], levels=args['levels_gph'], colors='white', linewidths=1.) labels = args['ax'].clabel(c, c.levels, inline=True, fmt='%4.0f', fontsize=6) labels2 = args['ax'].clabel(css, css.levels, inline=True, fmt='%4.0f', fontsize=7) plt.setp(labels2, path_effects=[ patheffects.withStroke(linewidth=0.5, foreground="w") ]) maxlabels = plot_maxmin_points(args['ax'], args['x'], args['y'], data['gh'], 'max', 150, symbol='H', color='royalblue', random=True) minlabels = plot_maxmin_points(args['ax'], args['x'], args['y'], data['gh'], 'min', 150, symbol='L', color='coral', random=True) an_fc = annotation_forecast(args['ax'], time) an_var = annotation( args['ax'], 'Geopotential height @500hPa [m] and temperature @850hPa [C]', loc='lower left', fontsize=6) an_run = annotation_run(args['ax'], run) logo = add_logo_on_map(ax=args['ax'], zoom=0.1, pos=(0.95, 0.08)) if first: plt.colorbar(cs, orientation='horizontal', label='Temperature', pad=0.03, fraction=0.04) if debug: plt.show(block=True) else: plt.savefig(filename, **options_savefig) remove_collections([ c, cs, css, labels, labels2, an_fc, an_var, an_run, maxlabels, minlabels, logo ]) first = False
def plot_cartopy(lons, lats, size, color, labels=None, projection='global', resolution='110m', continent_fill_color='0.8', water_fill_color='1.0', colormap=None, colorbar=None, marker="o", title=None, colorbar_ticklabel_format=None, show=True, proj_kwargs=None, **kwargs): # @UnusedVariable """ Creates a Cartopy plot with a data point scatter plot. :type lons: list/tuple of floats :param lons: Longitudes of the data points. :type lats: list/tuple of floats :param lats: Latitudes of the data points. :type size: float or list/tuple of floats :param size: Size of the individual points in the scatter plot. :type color: list/tuple of floats (or objects that can be converted to floats, like e.g. :class:`~obspy.core.utcdatetime.UTCDateTime`) :param color: Color information of the individual data points to be used in the specified color map (e.g. origin depths, origin times). :type labels: list/tuple of str :param labels: Annotations for the individual data points. :type projection: str, optional :param projection: The map projection. Currently supported are: * ``"global"`` (Will plot the whole world using :class:`~cartopy.crs.Mollweide`.) * ``"ortho"`` (Will center around the mean lat/long using :class:`~cartopy.crs.Orthographic`.) * ``"local"`` (Will plot around local events using :class:`~cartopy.crs.AlbersEqualArea`.) * Any other Cartopy :class:`~cartopy.crs.Projection`. An instance of this class will be created using the supplied ``proj_kwargs``. Defaults to "global" :type resolution: str, optional :param resolution: Resolution of the boundary database to use. Will be passed directly to the Cartopy module. Possible values are: * ``"110m"`` * ``"50m"`` * ``"10m"`` Defaults to ``"110m"``. For compatibility, you may also specify any of the Basemap resolutions defined in :func:`plot_basemap`. :type continent_fill_color: Valid matplotlib color, optional :param continent_fill_color: Color of the continents. Defaults to ``"0.9"`` which is a light gray. :type water_fill_color: Valid matplotlib color, optional :param water_fill_color: Color of all water bodies. Defaults to ``"white"``. :type colormap: str, any matplotlib colormap, optional :param colormap: The colormap for color-coding the events as provided in `color` kwarg. The event with the smallest `color` property will have the color of one end of the colormap and the event with the highest `color` property the color of the other end with all other events in between. Defaults to None which will use the default matplotlib colormap. :type colorbar: bool, optional :param colorbar: When left `None`, a colorbar is plotted if more than one object is plotted. Using `True`/`False` the colorbar can be forced on/off. :type title: str :param title: Title above plot. :type colorbar_ticklabel_format: str or function or subclass of :class:`matplotlib.ticker.Formatter` :param colorbar_ticklabel_format: Format string or Formatter used to format colorbar tick labels. :type show: bool :param show: Whether to show the figure after plotting or not. Can be used to do further customization of the plot before showing it. :type proj_kwargs: dict :param proj_kwargs: Keyword arguments to pass to the Cartopy :class:`~cartopy.ccrs.Projection`. In this dictionary, you may specify ``central_longitude='auto'`` or ``central_latitude='auto'`` to have this function calculate the latitude or longitude as it would for other projections. Some arguments may be ignored if you choose one of the built-in ``projection`` choices. """ import matplotlib.pyplot as plt if isinstance(color[0], (datetime.datetime, UTCDateTime)): datetimeplot = True color = [date2num(getattr(t, 'datetime', t)) for t in color] else: datetimeplot = False fig = plt.figure() # The colorbar should only be plotted if more then one event is # present. if colorbar is not None: show_colorbar = colorbar else: if len(lons) > 1 and hasattr(color, "__len__") and \ not isinstance(color, (str, native_str)): show_colorbar = True else: show_colorbar = False if projection == "local": ax_x0, ax_width = 0.10, 0.80 elif projection == "global": ax_x0, ax_width = 0.01, 0.98 else: ax_x0, ax_width = 0.05, 0.90 proj_kwargs = proj_kwargs or {} if projection == 'global': proj_kwargs['central_longitude'] = np.mean(lons) proj = ccrs.Mollweide(**proj_kwargs) elif projection == 'ortho': proj_kwargs['central_latitude'] = np.mean(lats) proj_kwargs['central_longitude'] = mean_longitude(lons) proj = ccrs.Orthographic(**proj_kwargs) elif projection == 'local': if min(lons) < -150 and max(lons) > 150: max_lons = max(np.array(lons) % 360) min_lons = min(np.array(lons) % 360) else: max_lons = max(lons) min_lons = min(lons) lat_0 = max(lats) / 2. + min(lats) / 2. lon_0 = max_lons / 2. + min_lons / 2. if lon_0 > 180: lon_0 -= 360 deg2m_lat = 2 * np.pi * 6371 * 1000 / 360 deg2m_lon = deg2m_lat * np.cos(lat_0 / 180 * np.pi) if len(lats) > 1: height = (max(lats) - min(lats)) * deg2m_lat width = (max_lons - min_lons) * deg2m_lon margin = 0.2 * (width + height) height += margin width += margin else: height = 2.0 * deg2m_lat width = 5.0 * deg2m_lon # Do intelligent aspect calculation for local projection # adjust to figure dimensions w, h = fig.get_size_inches() aspect = w / h if show_colorbar: aspect *= 1.2 if width / height < aspect: width = height * aspect else: height = width / aspect proj_kwargs['central_latitude'] = lat_0 proj_kwargs['central_longitude'] = lon_0 proj_kwargs['standard_parallels'] = [lat_0, lat_0] proj = ccrs.AlbersEqualArea(**proj_kwargs) # User-supplied projection. elif isinstance(projection, type): if 'central_longitude' in proj_kwargs: if proj_kwargs['central_longitude'] == 'auto': proj_kwargs['central_longitude'] = mean_longitude(lons) if 'central_latitude' in proj_kwargs: if proj_kwargs['central_latitude'] == 'auto': proj_kwargs['central_latitude'] = np.mean(lats) if 'pole_longitude' in proj_kwargs: if proj_kwargs['pole_longitude'] == 'auto': proj_kwargs['pole_longitude'] = np.mean(lons) if 'pole_latitude' in proj_kwargs: if proj_kwargs['pole_latitude'] == 'auto': proj_kwargs['pole_latitude'] = np.mean(lats) proj = projection(**proj_kwargs) else: msg = "Projection '%s' not supported." % projection raise ValueError(msg) if show_colorbar: map_ax = fig.add_axes([ax_x0, 0.13, ax_width, 0.77], projection=proj) cm_ax = fig.add_axes([ax_x0, 0.05, ax_width, 0.05]) plt.sca(map_ax) else: ax_y0, ax_height = 0.05, 0.85 if projection == "local": ax_y0 += 0.05 ax_height -= 0.05 map_ax = fig.add_axes([ax_x0, ax_y0, ax_width, ax_height], projection=proj) if projection == 'local': x0, y0 = proj.transform_point(lon_0, lat_0, proj.as_geodetic()) map_ax.set_xlim(x0 - width / 2, x0 + width / 2) map_ax.set_ylim(y0 - height / 2, y0 + height / 2) else: map_ax.set_global() # Pick features at specified resolution. resolution = _CARTOPY_RESOLUTIONS[resolution] try: borders, land, ocean = _CARTOPY_FEATURES[resolution] except KeyError: borders = cfeature.NaturalEarthFeature(cfeature.BORDERS.category, cfeature.BORDERS.name, resolution, edgecolor='none', facecolor='none') land = cfeature.NaturalEarthFeature(cfeature.LAND.category, cfeature.LAND.name, resolution, edgecolor='face', facecolor='none') ocean = cfeature.NaturalEarthFeature(cfeature.OCEAN.category, cfeature.OCEAN.name, resolution, edgecolor='face', facecolor='none') _CARTOPY_FEATURES[resolution] = (borders, land, ocean) # Draw coast lines, country boundaries, fill continents. if MATPLOTLIB_VERSION >= [2, 0, 0]: map_ax.set_facecolor(water_fill_color) else: map_ax.set_axis_bgcolor(water_fill_color) map_ax.add_feature(ocean, facecolor=water_fill_color) map_ax.add_feature(land, facecolor=continent_fill_color) map_ax.add_feature(borders, edgecolor='0.75') map_ax.coastlines(resolution=resolution, color='0.4') # Draw grid lines - TODO: draw_labels=True doesn't work yet. if projection == 'local': map_ax.gridlines() else: # Draw lat/lon grid lines every 30 degrees. map_ax.gridlines(xlocs=range(-180, 181, 30), ylocs=range(-90, 91, 30)) # Plot labels if labels and len(lons) > 0: with map_ax.hold_limits(): for name, xpt, ypt, _colorpt in zip(labels, lons, lats, color): map_ax.text(xpt, ypt, name, weight="heavy", color="k", zorder=100, transform=ccrs.Geodetic(), path_effects=[ PathEffects.withStroke(linewidth=3, foreground="white") ]) scatter = map_ax.scatter(lons, lats, marker=marker, s=size, c=color, zorder=10, cmap=colormap, transform=ccrs.Geodetic()) if title: plt.suptitle(title) # Only show the colorbar for more than one event. if show_colorbar: if colorbar_ticklabel_format is not None: if isinstance(colorbar_ticklabel_format, (str, native_str)): formatter = FormatStrFormatter(colorbar_ticklabel_format) elif hasattr(colorbar_ticklabel_format, '__call__'): formatter = FuncFormatter(colorbar_ticklabel_format) elif isinstance(colorbar_ticklabel_format, Formatter): formatter = colorbar_ticklabel_format locator = MaxNLocator(5) else: if datetimeplot: locator = AutoDateLocator() formatter = AutoDateFormatter(locator) # Compat with old matplotlib versions. if hasattr(formatter, "scaled"): formatter.scaled[1 / (24. * 60.)] = '%H:%M:%S' else: locator = None formatter = None cb = Colorbar(cm_ax, scatter, cmap=colormap, orientation='horizontal', ticks=locator, format=formatter) # Compat with old matplotlib versions. if hasattr(cb, "update_ticks"): cb.update_ticks() if show: plt.show() return fig
# It's just for the high level understanding. Plus xkcd style is pretty plt.xkcd() mycol = '#343535' plt.rcParams["font.family"] = "Concourse T4" plt.rcParams["axes.linewidth"] = 2 plt.rcParams["axes.edgecolor"] = mycol plt.rcParams["text.color"] = mycol plt.rcParams["xtick.color"] = mycol plt.rcParams["ytick.color"] = mycol plt.rcParams["ytick.minor.width"] = 0 # Removes remaining white lines after xkcdifying the plot. # Changing the background didn't fix it. mpl.rcParams['path.effects'] = [patheffects.withStroke(linewidth=0)] fig = plt.figure(figsize=(10, 5)) ax = fig.add_subplot(1, 1, 1) def y_fmt(y, pos): return '{:,.1f}%'.format(y) ax.get_yaxis().set_major_formatter(FuncFormatter(y_fmt)) # ax.get_xaxis().set_major_formatter(mdates.DateFormatter('%Y')) ax.spines['right'].set_color('none') ax.spines['top'].set_color('none')
def visualise_orientational_distribution(self, axes_to_return=None, cbar=True): """ Creates a plot of the orientational distribution of the unit cells. :param axes_to_return: if None, print to screen, otherwise, requires 3 axes objects, and will return them. :param cbar: boolean to specify if a color bar should be used. """ import matplotlib.pyplot as plt import matplotlib.patheffects as patheffects from mpl_toolkits.basemap import Basemap import scipy.ndimage as ndi def cart2sph(x, y, z): # cctbx (+z to source, y to ceiling) to # lab frame (+x to source, z to ceiling) z, x, y = x, y, z dxy = np.sqrt(x**2 + y**2) r = np.sqrt(dxy**2 + z**2) theta = np.arctan2(y, x) phi = np.arctan2(z, dxy) # angle of the z axis relative to xy plane theta, phi = np.rad2deg([theta, phi]) return theta % 360, phi, r def xy_lat_lon_from_orientation(orientation_array, axis_id): logger.debug("axis_id: {}".format(axis_id)) dist = math.sqrt(orientation_array[axis_id][0]**2 + orientation_array[axis_id][1]**2 + orientation_array[axis_id][2]**2) flon, flat, bla = cart2sph(orientation_array[axis_id][0] / dist, orientation_array[axis_id][1] / dist, orientation_array[axis_id][2] / dist) x, y = euler_map(flon, flat) return x, y, flon, flat orientations = [ flex.vec3_double(flex.double(image.orientation.direct_matrix())) for image in self.members ] space_groups = [ image.orientation.unit_cell().lattice_symmetry_group() for image in self.members ] # Now do all the plotting if axes_to_return is None: plt.figure(figsize=(10, 14)) axes_to_return = [ plt.subplot2grid((3, 1), (0, 0)), plt.subplot2grid((3, 1), (1, 0)), plt.subplot2grid((3, 1), (2, 0)) ] show_image = True else: assert len(axes_to_return) == 3, "If using axes option, must hand" \ " 3 axes to function." show_image = False axis_ids = [0, 1, 2] labels = ["a", "b", "c"] for ax, axis_id, label in zip(axes_to_return, axis_ids, labels): # Lists of x,y,lat,long for the master orientation, and for all # symmetry mates. x_coords = [] y_coords = [] lon = [] lat = [] sym_x_coords = [] sym_y_coords = [] sym_lon = [] sym_lat = [] euler_map = Basemap(projection='eck4', lon_0=0, ax=ax) for orientation, point_group_type in zip(orientations, space_groups): # Get position of main spots. main_x, main_y, main_lon, main_lat \ = xy_lat_lon_from_orientation(list(orientation), axis_id) x_coords.append(main_x) y_coords.append(main_y) lon.append(main_lon) lat.append(main_lat) # Get position of symetry mates symmetry_operations = list(point_group_type.smx())[1:] for mx in symmetry_operations: rotated_orientation = list(mx.r().as_double() * orientation) # <-- # should make sense if orientation was a vector, not clear what is # going on since orientation is a matrix. Or, make some test cases # with 'orientation' and see if the behave as desired. sym_x, sym_y, sym_lo, sym_la \ = xy_lat_lon_from_orientation(rotated_orientation, axis_id) #assert (sym_x, sym_y) != (main_x, main_y) sym_x_coords.append(sym_x) sym_y_coords.append(sym_y) sym_lon.append(sym_lo) sym_lat.append(sym_la) # Plot each image as a yellow sphere logger.debug(len(x_coords)) euler_map.plot(x_coords, y_coords, 'oy', markersize=4, markeredgewidth=0.5) # Plot the symetry mates as black crosses #euler_map.plot(sym_x_coords, sym_y_coords, 'kx') # Use a histogram to bin the data in lattitude/longitude space, smooth it, # then plot this as a contourmap. This is for all the symetry-related # copies #density_hist = np.histogram2d(lat + sym_lat, lon + sym_lon, # bins=[range(-90, 91), range(0, 361)]) # No symmetry mates until we can verify what the cctbx libs are doing density_hist = np.histogram2d( lat, lon, bins=[list(range(-90, 91)), list(range(0, 361))]) smoothed = ndi.gaussian_filter(density_hist[0], (15, 15), mode='wrap') local_intensity = [] x_for_plot = [] y_for_plot = [] for _lat in range(0, 180): for _lon in range(0, 360): _x, _y = euler_map(density_hist[2][_lon], density_hist[1][_lat]) x_for_plot.append(_x) y_for_plot.append(_y) local_intensity.append(smoothed[_lat, _lon]) cs = euler_map.contourf(np.array(x_for_plot), np.array(y_for_plot), np.array(local_intensity), tri=True) # Pretty up graph if cbar: _cbar = plt.colorbar(cs, ax=ax) _cbar.ax.set_ylabel('spot density [AU]') middle = euler_map(0, 0) path_effect = [patheffects.withStroke(linewidth=3, foreground="w")] euler_map.plot(middle[0], middle[1], 'o', markersize=10, mfc='none') euler_map.plot(middle[0], middle[1], 'x', markersize=8) ax.annotate("beam", xy=(0.52, 0.52), xycoords='axes fraction', size='medium', path_effects=path_effect) euler_map.drawmeridians(np.arange(0, 360, 60), labels=[0, 0, 1, 0], fontsize=10) euler_map.drawparallels(np.arange(-90, 90, 30), labels=[1, 0, 0, 0], fontsize=10) ax.annotate(label, xy=(-0.05, 0.9), xycoords='axes fraction', size='x-large', weight='demi') if show_image: plt.show() return axes_to_return
def draw_velocity_map(nc_file_name): nc = NetCDFFile(nc_file_name, 'r+') lat = nc.variables['nav_lat_grid_U'][:] lon = nc.variables['nav_lon_grid_U'][:] vel_dir = "samples/bad/vel/" nc_name = nc_file_name.split("/")[4].split(".")[0] velocity = np.zeros((400, 1100), dtype=np.float32) for file_name in os.listdir(vel_dir): if nc_name in file_name: square = img.load_square_from_file(vel_dir + file_name.split(".")[0]) print(file_name) print(str(np.min(square)) + "; " + str(np.max(square))) square_index = data.extract_square_index(vel_dir + file_name.split(".")[0]) x = int(square_index.split("_")[0]) y = int(square_index.split("_")[1]) print(str(x) + " " + str(y)) velocity[y:y + 100, x:x + 100] = square nc.close() lat_left_bottom = lat[-1][-1] lon_left_bottom = lon[-1][-1] lat_right_top = lat[0][0] lon_right_top = lon[0][0] lat_center = 90 # 110, 119 lon_center = 110 m = Basemap(projection='stere', lon_0=lon_center, lat_0=lat_center, resolution='l', llcrnrlat=lat_left_bottom, llcrnrlon=lon_left_bottom, urcrnrlat=lat_right_top, urcrnrlon=lon_right_top) m.pcolormesh(lon, lat, velocity, latlon=True, cmap='RdYlBu_r', vmax=0.6) m.drawcoastlines() m.drawcountries() m.fillcontinents(color='#cc9966', lake_color='#99ffff') # plt.rcParams.update({'font.size': 22}) ax = plt.gca() # ax.tick_params(labelsize=10) divider = make_axes_locatable(ax) cax = divider.append_axes("right", size="5%", pad=0.05) plt.colorbar(cax=cax, label="Sea current velocity") # plt.title("Anomalies detection results for: " + "20 March, 2013") model = load_model("samples/current_model/model.h5") valid_squares = [[*list(range(1, 10))]] with open("samples/valid_samples.csv", 'r', newline='') as csvfile: samples = [] reader = csv.reader(csvfile, delimiter=',') for row in reader: if "samples/bad/vel/" + nc_name in row[0]: print(row) samples.append(row) square_index = data.extract_square_index(row[0]) x = int(square_index.split("_")[0]) y = int(square_index.split("_")[1]) if (x >= 100) and (x < 1000) and (y < 300): sample = np.zeros((1, 100, 100, 1), dtype=np.float32) square = np.expand_dims(img.load_square_from_file(row[0]), axis=2) sample[0] = square result = model.predict(sample) result_x, result_y = m(lon[y + 50][x + 50], lat[y + 50][x + 50]) ax.text(result_x, result_y, "%0.3f" % result[0][0], ha='center', size=7, color="yellow", path_effects=[ PathEffects.withStroke(linewidth=3, foreground='black') ]) if row[1] == "1": print("outlier!") lat_poly = np.array([ lat[y][x], lat[y][x + 99], lat[y + 99][x + 99], lat[y + 99][x] ]) lon_poly = np.array([ lon[y][x], lon[y][x + 99], lon[y + 99][x + 99], lon[y + 99][x] ]) mapx, mapy = m(lon_poly, lat_poly) points = np.zeros((4, 2), dtype=np.float32) for j in range(0, 4): points[j][0] = mapx[j] points[j][1] = mapy[j] if result[0][0] > 0.5: poly = Polygon(points, color='green', fill=False, linewidth=3) ax.add_patch(poly) else: poly = Polygon(points, color='red', fill=False, linewidth=3) ax.add_patch(poly) else: if result[0][0] > 0.5: lat_poly = np.array([ lat[y][x], lat[y][x + 99], lat[y + 99][x + 99], lat[y + 99][x] ]) lon_poly = np.array([ lon[y][x], lon[y][x + 99], lon[y + 99][x + 99], lon[y + 99][x] ]) mapx, mapy = m(lon_poly, lat_poly) points = np.zeros((4, 2), dtype=np.float32) for j in range(0, 4): points[j][0] = mapx[j] points[j][1] = mapy[j] poly = Polygon(points, color='red', fill=False, linewidth=3) ax.add_patch(poly) print(result) # plt.show() red = Patch(color='red', label='Error') green = Patch(color='green', label='Correct') plt.legend(loc='lower right', fontsize='medium', bbox_to_anchor=(1, 1), handles=[green, red]) plt.savefig("test" + "_bad_result.png", dpi=500)
def plot_log(logfiles, hours): end = datetime.datetime.now() begin = end - datetime.timedelta(hours=hours) #load all logfiles data = None for logfile in logfiles: try: d = pd.read_csv(logfile, parse_dates=[0]) if data is not None: data = pd.concat((data, d)) else: data = d except: logging.error("error while loading file " + logfile) return 0 #ipdb.set_trace() data = data.sort('time') data = data[data.time > begin] data = data.set_index(pd.DatetimeIndex(data.time)) data = data.drop("time", axis=1) #ipdb.set_trace() plt.xkcd() rcp['path.effects'] = [patheffects.withStroke(linewidth=0)] #all columns for item, frame in data.iteritems(): if frame is None or frame.empty or frame.isnull().values.all(): continue f = plt.figure() #f.patch.set_facecolor("#ccefff") #f.patch.set_alpha("0.0") logging.debug("column " + str(item) + " " + frame.name) plt.plot(data.index.to_pydatetime(), frame)#"b" ax = plt.gca() #ax.grid(True, linewidth=1.0) #plt.xlim(begin, end) #ax.spines['right'].set_visible(False) #ax.spines['top'].set_visible(False) ax.yaxis.set_ticks_position('none')#('left') ax.xaxis.set_ticks_position('none')#('bottom') try: #might not work if few data available f.autofmt_xdate() #plt.tick_params(which='minor', length=4) #plt.tick_params(which='major', length=5) #ipdb.set_trace() #ax.fmt_xdata = AutoDateFormatter('%d.%m/%H') #ax.xaxis.set_major_locator(WeekdayLocator(MONDAY)) ax.xaxis.set_major_locator(AutoDateLocator()) ax.xaxis.set_major_formatter(AutoDateFormatter(defaultfmt='%d.%m')) #f.autofmt_xdate() except: logging.debug("Plot: Few data!") #plt.xlabel('Datum') #plt.ylabel('Temperatur / C') outfile = "app/static/log_" + str(item) + ".png" logging.debug("Plot plot_log " + str(datetime.datetime.now())) #480x320 plt.gcf().set_size_inches(5.3, 2.4) plt.tight_layout() plt.savefig(outfile, dpi=70, transparent=True, bbox_inches='tight') plt.close() logging.debug("Plot: End plot_log " + str(datetime.datetime.now()))
def show_map(target_cases: float, show_map: bool, country: str): ''' Show a map of the US with T-XXX (to N cases) shown on the states. ''' # Load the dataset. with open(DATA_FILENAME, 'rb') as f: data: pd.DataFrame = pickle.load(f) # Setup the reference curve. curve = ReferenceCurve(data, use_spline=True) # Load the geo data. usa = gpd.read_file(path.join('data', 'states.shp')) usa = usa[~usa.STATE_ABBR.isin(['AK', 'HI'])] # Restrict to US data, and confirmed cases only. data = data[data['Country/Region'] == country] # Calculate days until the target for each state. estimated_target_cases_day = int(curve.cases_to_day(target_cases)) data['Province/State'] = data['Province/State'].fillna('ALL') if show_map: state_names = [x.STATE_NAME for _, x in usa.iterrows()] else: state_names = data['Province/State'].unique() state_to_data: Dict[str, pd.DataFrame] = {} state_to_days_until: Dict[str, int] = {} for state_name in state_names: # Get confirmed cases by day state_data = data[data['Province/State'] == state_name] state_data = state_data[['Confirmed', FILE_DATE_KEY ]].sort_values(by=[FILE_DATE_KEY]) state_data = state_data.groupby(FILE_DATE_KEY).sum() state_data.reset_index( level=0, inplace=True) # Convert the index (of the date) to a column. if len(state_data) == 0: continue cur_cases = int(state_data.iloc[-1]['Confirmed']) estimated_cur_day = int(curve.cases_to_day(cur_cases)) estimated_cur_day = max( 0, estimated_cur_day ) # Don't let it get < 0 or else it throws ranges off. state_to_data[state_name] = state_data state_to_days_until[ state_name] = estimated_target_cases_day - estimated_cur_day # If not show if not show_map: table = [[ 'State', 'Current confirmed', f'Days until {int(target_cases)} cases' ]] for state in sorted(state_to_days_until.keys()): table.append([ state, state_to_data[state].iloc[-1]['Confirmed'], state_to_days_until[state] ]) print(tabulate(table[1:], headers=table[0])) return # Set the 'days_until' column. usa['days_until'] = usa['STATE_NAME'].map(lambda x: state_to_days_until[x]) def remap01(x, start, end): return start + (end - start) * x # Draw the whole map. cmap = plt.get_cmap('jet') cmap = [cmap(int(remap01(x, 0, 1))) for x in range(256)] cmap_reversed = ListedColormap(cmap[::-1]) usa.plot(column='days_until', cmap=cmap_reversed, edgecolor='black') days_until_min = min(state_to_days_until.values()) days_until_max = max(state_to_days_until.values()) # Draw stuff on each state. for _, state_geo in usa.iterrows(): # Get confirmed cases by day state_data = state_to_data[state_geo.STATE_NAME] cur_cases = int(state_data.iloc[-1]['Confirmed']) days_until = state_to_days_until[state_geo.STATE_NAME] # Figure out a text color. t = (days_until - days_until_min) / (days_until_max - days_until_min) color = cmap_reversed(int(t * 255)) #x = usa[usa.STATE_NAME == state_geo.STATE_NAME] #x.plot() pt = state_geo.geometry.representative_point() txt = plt.text(pt.x, pt.y, f'{state_geo.STATE_ABBR}\nT-{days_until} days', horizontalalignment='center', color='white') txt.set_path_effects( [PathEffects.withStroke(linewidth=2, foreground='black')]) highest_date = data[FILE_DATE_KEY].max() plt.title( f'From {highest_date}, days until {int(target_cases):,} (known) cases') plt.show()
def _plot(self, configs, params, fn=None, log_c=False, logy=False): """ Parameters ---------- configs: List[Configuration] configs to be plotted params: List[str] parameters to be plotted fn: str filename to save plot in log_c: bool whether to use log-scaled colormap logy: bool whether the cost-axis should be logscale Returns ------- output: str """ if fn is None: filename = os.path.join(self.output_dir, "parallel_coordinates_" + str(len(configs)) + '.png') else: filename = fn if len(params) < 3: self.logger.info("Only two parameters, skipping parallel coordinates.") return # Create dataframe with configs cost_str = ('log-' if logy else '') + ('runtime' if self.runtime else 'cost') data = [] for conf in configs: conf_dict = conf.get_dictionary() new_entry = {} # Add cost-column new_entry[cost_str] = self._fun(self.config_to_cost[conf], logy) # Add parameters for p in params: # Catch key-errors (implicate unused hyperparameter) value = conf_dict.get(p) if value is None: # Value is None, parameter unused # TODO new_entry[p] = 0 continue param = self.cs.get_hyperparameter(p) if isinstance(param, IntegerHyperparameter): new_entry[p] = int(value) elif isinstance(param, FloatHyperparameter): new_entry[p] = float(value) elif isinstance(param, CategoricalHyperparameter): new_entry[p] = param.choices.index(value) elif isinstance(param, Constant): new_entry[p] = float(value) else: raise RuntimeError('No rule for parametertype %s' % str(type(param))) data.append(pd.Series(new_entry)) data = pd.DataFrame(data) # Add 'cost' to params, params serves as index for dataframe params = [cost_str] + params # Select only parameters we want to plot (specified in index) data = data[params] # Create subplots fig, axes = plt.subplots(1, len(params) - 1, sharey=False, figsize=(15, 5)) # Normalize the data for each parameter, so the displayed ranges are # meaningful. Note that the ticklabels are set to original data. min_max_diff = {} for p in params: # TODO enable full parameter scale # hyper = self.cs.get_hyperparameter(p) # if isinstance(hyper, CategoricalHyperparameter): # lower = 0 # upper = len(hyper.choices)-1 # else: # lower, upper = self.cs.get_hyperparameter(p).lower, self.cs.get_hyperparameter(p).upper # min_max_diff[p] = [lower, upper, upper - lower] # data[p] = np.true_divide(data[p] - lower, upper - lower) # Check if explored values are more than one min_max_diff[p] = [data[p].min(), data[p].max(), np.ptp(data[p])] if len(np.unique(data[p])) <= 1: self.logger.debug("%s has only one explored value (%s)", p, np.unique(data[p])) data[p] = np.ones(data[p].shape) else: data[p] = np.true_divide(data[p] - data[p].min(), np.ptp(data[p])) # setup colormap cm = plt.get_cmap('winter') scaler = colors.LogNorm if log_c else colors.Normalize if self.worst_config_performance < self.best_config_performance: normedC = scaler(vmin=self.worst_config_performance, vmax=self.best_config_performance) else: normedC = scaler(vmax=self.worst_config_performance, vmin=self.best_config_performance) scale = cmx.ScalarMappable(norm=normedC, cmap=cm) # Plot data for i, ax in enumerate(axes): # Iterate over params for idx in data.index[::-1]: # Iterate over configs cval = scale.to_rgba(self._fun(self.config_to_cost[configs[idx]], logy)) cval = (cval[2], cval[0], cval[1]) zorder = idx - 5 if idx > len(data) // 2 else len(data) - idx # -5 to have the best on top of the worst alpha = (zorder / len(data)) - 0.25 alpha = np.clip(alpha, 0, 1) path_effects = [path_efx.Normal()] if idx in [0, 1, 2, 3, 4, len(data) - 1, len(data) - 2, len(data) - 3, len(data) - 4, len(data) - 5]: alpha = 1 path_effects = [path_efx.withStroke(linewidth=10, foreground='k')] #self.logger.debug(data.loc[idx, params]) ax.plot(range(len(params)), data.loc[idx, params], color=cval, alpha=alpha, linewidth=6, zorder=zorder, path_effects=path_effects) ax.set_xlim([i, i + 1]) def set_ticks_for_axis(p, ax, num_ticks=10): minimum, maximum, param_range = min_max_diff[params[p]] # self.logger.debug("Ticks for parameter %s: Min %f, Max %f, Range %f", p, minimum, maximum, param_range) hyper = p if p > 0: # First column not a parameter, but cost... hyper = self.cs.get_hyperparameter(params[p]) if isinstance(hyper, CategoricalHyperparameter): num_ticks = len(hyper.choices) step = 1 tick_labels = hyper.choices norm_min = data[params[p]].min() norm_range = np.ptp(data[params[p]]) if num_ticks > 1: norm_step = norm_range / float(num_ticks - 1) ticks = [round(norm_min + norm_step * i, 2) for i in range(num_ticks)] else: ticks = [1] elif isinstance(hyper, Constant): ticks = [1] tick_labels = [hyper.value] else: step = param_range / float(num_ticks) if isinstance(hyper, IntegerHyperparameter): tick_labels = [int(minimum + step * i) for i in range(num_ticks + 1)] else: tick_labels = [round(minimum + step * i, 2) for i in range(num_ticks + 1)] norm_min = data[params[p]].min() norm_range = np.ptp(data[params[p]]) norm_step = norm_range / float(num_ticks) ticks = [round(norm_min + norm_step * i, 2) for i in range(num_ticks + 1)] ax.yaxis.set_ticks(ticks) ax.set_yticklabels(tick_labels) # TODO adjust tick-labels to unused ranges of parameters and maybe even log? plt.xticks(rotation=5) for p, ax in enumerate(axes): ax.xaxis.set_major_locator(ticker.FixedLocator([p])) set_ticks_for_axis(p, ax, num_ticks=6) ax.set_xticklabels([params[p]], rotation=5) setp(ax.get_yticklabels(), fontsize=15) setp(ax.get_xticklabels(), fontsize=15) # Move the final axis' ticks to the right-hand side ax = plt.twinx(axes[-1]) dim = len(axes) ax.xaxis.set_major_locator(ticker.FixedLocator([len(params) - 2, len(params) - 1])) set_ticks_for_axis(dim, ax, num_ticks=6) ax.set_xticklabels([params[-2], params[-1]]) ax.set_ylim(axes[-1].get_ylim()) setp(ax.get_yticklabels(), fontsize=15) # Remove spaces between subplots plt.subplots_adjust(wspace=0) plt.tight_layout() plt.subplots_adjust(wspace=0) fig.savefig(filename) plt.close(fig) return filename
def __setup_measure(self): dashesAvg = [4, 5, 1, 5, 1, 5] dashesGM = [5, 5, 5, 5, 1, 5, 1, 5] dashesHalf = [1, 5, 5, 5, 5, 5] self.lines[Markers.MIN] = Line2D([0, 0], [0, 0], linestyle='--', color='black') self.lines[Markers.MAX] = Line2D([0, 0], [0, 0], linestyle='-.', color='black') self.lines[Markers.AVG] = Line2D([0, 0], [0, 0], dashes=dashesAvg, color='magenta') self.lines[Markers.GMEAN] = Line2D([0, 0], [0, 0], dashes=dashesGM, color='green') self.lines[Markers.HP] = Line2D([0, 0], [0, 0], dashes=dashesHalf, color='purple') self.lines[Markers.HFS] = Line2D([0, 0], [0, 0], dashes=dashesHalf, color='purple') self.lines[Markers.HFE] = Line2D([0, 0], [0, 0], dashes=dashesHalf, color='purple') self.lines[Markers.OP] = Line2D([0, 0], [0, 0], dashes=dashesHalf, color='#996600') self.lines[Markers.OFS] = Line2D([0, 0], [0, 0], dashes=dashesHalf, color='#996600') self.lines[Markers.OFE] = Line2D([0, 0], [0, 0], dashes=dashesHalf, color='#996600') if matplotlib.__version__ >= '1.3': effect = patheffects.withStroke(linewidth=3, foreground="w", alpha=0.75) self.lines[Markers.MIN].set_path_effects([effect]) self.lines[Markers.MAX].set_path_effects([effect]) self.lines[Markers.AVG].set_path_effects([effect]) self.lines[Markers.GMEAN].set_path_effects([effect]) self.lines[Markers.HP].set_path_effects([effect]) self.lines[Markers.HFS].set_path_effects([effect]) self.lines[Markers.HFE].set_path_effects([effect]) self.lines[Markers.OP].set_path_effects([effect]) self.lines[Markers.OFS].set_path_effects([effect]) self.lines[Markers.OFE].set_path_effects([effect]) for line in self.lines.itervalues(): self.axes.add_line(line) bbox = self.axes.bbox box = dict(boxstyle='round', fc='white', ec='black', clip_box=bbox) self.labels[Markers.MIN] = Text(0, 0, 'Min', fontsize='xx-small', ha="right", va="bottom", bbox=box, color='black') self.labels[Markers.MAX] = Text(0, 0, 'Max', fontsize='xx-small', ha="right", va="top", bbox=box, color='black') box['ec'] = 'magenta' self.labels[Markers.AVG] = Text(0, 0, 'Mean', fontsize='xx-small', ha="right", va="center", bbox=box, color='magenta') box['ec'] = 'green' self.labels[Markers.GMEAN] = Text(0, 0, 'GMean', fontsize='xx-small', ha="right", va="center", bbox=box, color='green') box['ec'] = 'purple' self.labels[Markers.HP] = Text(0, 0, '-3dB', fontsize='xx-small', ha="right", va="center", bbox=box, color='purple') self.labels[Markers.HFS] = Text(0, 0, '-3dB Start', fontsize='xx-small', ha="center", va="top", bbox=box, color='purple') self.labels[Markers.HFE] = Text(0, 0, '-3dB End', fontsize='xx-small', ha="center", va="top", bbox=box, color='purple') box['ec'] = '#996600' self.labels[Markers.OP] = Text(0, 0, 'OBW', fontsize='xx-small', ha="right", va="center", bbox=box, color='#996600') self.labels[Markers.OFS] = Text(0, 0, 'OBW Start', fontsize='xx-small', ha="center", va="top", bbox=box, color='#996600') self.labels[Markers.OFE] = Text(0, 0, 'OBW End', fontsize='xx-small', ha="center", va="top", bbox=box, color='#996600') for label in self.labels.itervalues(): self.axes.add_artist(label)
def fill_ugcs(self, data, bins=None, **kwargs): """Overlay filled UGC geometries The logic for plotting is a bit tricky due to fire zones overlapping forecast zones. In general, provide the zone code if you want it to display on top. Otherwise, I attempt to place forecast zones overtop fire weather zones. Args: data(dict): A dictionary of 6 char UGC code keys and values bins(list, optional): Bins to use for cloropleth, default 0:101:10 plotmissing(bool, optional): Should missing UGC data be plotted? """ if bins is None: bins = np.arange(0, 101, 10) cmap = stretch_cmap(kwargs.get('cmap'), bins) norm = mpcolors.BoundaryNorm(bins, cmap.N) # Figure out if we have zones or counties/parishes counties = True for key in data: if key[2] == 'Z': counties = False break ugcs = load_pickle_geo( "ugcs_county.pickle" if counties else "ugcs_zone.pickle") filter_func = true_filter if self.sector == 'state': filter_func = state_filter elif self.sector == 'cwa': filter_func = cwa_filter ilabel = kwargs.get('ilabel', False) plotmissing = kwargs.get('plotmissing', True) for ugc in ugcs: ugcdict = ugcs[ugc] if not filter_func(self, ugc, ugcdict): continue if data.get(ugc.decode('utf-8')) is None: if not plotmissing: continue # Holy cow, it appears values above 300 are always firewx, # so lets ignore these when we have no data! if not counties and int(ugc[3:]) >= 300: continue c = 'white' val = '-' z = Z_OVERLAY else: val = data[ugc.decode('utf-8')] c = cmap(norm([ val, ]))[0] z = Z_OVERLAY2 for polyi, polygon in enumerate(ugcdict.get(b'geom', [])): if polygon.exterior is None: continue arr = np.asarray(polygon.exterior) points = self.ax.projection.transform_points( ccrs.Geodetic(), arr[:, 0], arr[:, 1]) p = Polygon(points[:, :2], fc=c, ec='k', zorder=z, lw=.1) if z == Z_OVERLAY: self.ax.add_patch(p) if z == Z_OVERLAY2: self.ax.add_patch(p) if polyi == 0 and ilabel: mx = polygon.centroid.x my = polygon.centroid.y txt = self.ax.text(mx, my, '%s' % (val, ), zorder=100, ha='center', va='center', transform=ccrs.PlateCarree()) txt.set_path_effects( [PathEffects.withStroke(linewidth=2, foreground="w")]) if 'cmap' in kwargs: del kwargs['cmap'] self.draw_colorbar(bins, cmap, norm, **kwargs)
clim=(-1.5, 2.3)) # removing the tickmarks and labels for the 2D spectrum ax01.xaxis.set_ticks_position('none') ax01.yaxis.set_ticks_position('none') ax01.set_yticklabels([]) ax01.set_xticklabels([]) # white text with black outline txt = ax01.text(0.023, 0.73, '%s-band' % (band), size=20.5, color='w', transform=ax01.transAxes) txt.set_path_effects([PathEffects.withStroke(linewidth=3, foreground='k')]) f.add_subplot(ax01) # adds the subplot to the image # 1D spectrum ax02 = plt.Subplot(f, gs011[1]) ax02.step(wavelength, galspec1d_line1, where='mid', lw=2.3) ax02.fill_between(wavelength, error1d, error1d * -1, alpha=0.2) ax02.set_xlim(wavelength[74], wavelength[174]) ax02.set_ylabel(r'F$_{\lambda}$ [10$^{-18}$ erg/s/cm$^2$/$\AA$]', fontsize=16) ax02.set_xlabel('observed wavelength [microns]', labelpad=5, fontsize=16) f.add_subplot(ax02) # adds the subplot to the image # --> LEFT SIDE: F160W STAMP gs002 = gridspec.GridSpecFromSubplotSpec(1, 1, subplot_spec=gs01[0]) ax002 = plt.Subplot(
def plot_drafts_above( r_query: Query, ax_in: Axes, width, r_name: str = "Opposition", d_name: str = "Opposition", ) -> list: """Plot the draft lines from a replay above an axes Arguments: replay {Replay} -- Replay object containing the TeamSelections. ax_in {Axes} -- Axes to plot on. Keyword Arguments: r_name {str} -- Radiant team name. (default: {"Opposition"}) d_name {str} -- Dire team name. (default: {"Opposition"}) Returns: list -- List of generated plotted objects. """ replay: Replay = r_query.one() extra_ents = [] for t in replay.teams: if len(t.draft) == 0: print(f"No draft for {t.team} in {replay.replayID}") continue if t.team == Team.RADIANT: rdraft = process_team_portrait(replay, t) rdraft.thumbnail((width, rdraft.size[1] * width / rdraft.size[0]), ANTIALIAS) rdraft.thumbnail((width, rdraft.size[1] * width / rdraft.size[0]), ANTIALIAS) r_draft_box = make_image_annotation2(rdraft, ax_in, x=0.5, y=1.1, size=0.78) r_name_box = ax_in.text(s=r_name, x=0, y=1.0 + 0.18, path_effects=[ PathEffects.withStroke(linewidth=3, foreground="w") ], ha='left', va='bottom', zorder=5, color='#598307') extra_ents += [r_draft_box, r_name_box] else: ddraft = process_team_portrait(replay, t) ddraft.thumbnail((width, ddraft.size[1] * width / ddraft.size[0]), ANTIALIAS) d_draft_box = make_image_annotation2(ddraft, ax_in, x=0.5, y=1.0, size=0.78) d_name_box = ax_in.text(s=d_name, x=0.0, y=1.0 + 0.08, path_effects=[ PathEffects.withStroke(linewidth=3, foreground="w") ], ha='left', va='bottom', zorder=5, color='#A83806') extra_ents += [d_draft_box, d_name_box] return extra_ents
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt import matplotlib.patheffects as PathEffects pgconn = psycopg2.connect(database='coop', host='iemdb', user='******') ctx = get_autoplot_context(fdict, get_description()) station = ctx['station'] varname = ctx['varname'] year = ctx['year'] network = "%sCLIMATE" % (station[:2], ) nt = NetworkTable(network) table = "alldata_%s" % (station[:2], ) df = read_sql(""" with obs as (select month, year, high, lag(high) OVER (ORDER by day ASC) as lhigh, low, lag(low) OVER (ORDER by day ASC) as llow from """ + table + """ where station = %s) SELECT year, month, sum(case when high > lhigh then 1 else 0 end)::numeric as high_greater, sum(case when high = lhigh then 1 else 0 end)::numeric as high_unch, sum(case when high < lhigh then 1 else 0 end)::numeric as high_lower, sum(case when low > llow then 1 else 0 end)::numeric as low_greater, sum(case when low = llow then 1 else 0 end)::numeric as low_unch, sum(case when low < llow then 1 else 0 end)::numeric as low_lower from obs GROUP by year, month ORDER by year, month """, pgconn, params=(station, ), index_col=None) gdf = df.groupby('month').sum() gyear = df[df['year'] == year].groupby('month').sum() increase = gdf[varname + '_greater'] nochange = gdf[varname + '_unch'] decrease = gdf[varname + '_lower'] increase2 = gyear[varname + '_greater'] nochange2 = gyear[varname + '_unch'] decrease2 = gyear[varname + '_lower'] (fig, ax) = plt.subplots(1, 1, figsize=(8, 6)) total = decrease + nochange + increase total2 = decrease2 + nochange2 + increase2 ax.bar(total.index.values - 0.2, decrease / total * 100.0, fc='b', label='Decrease', width=0.4, align='center') ax.bar(total2.index.values + 0.2, decrease2 / total2 * 100.0, fc='lightblue', width=0.4, label="%s ''" % (year, ), align='center') ax.bar(total.index.values - 0.2, nochange / total * 100.0, bottom=(decrease / total * 100.0), fc='g', label="No Change", width=0.4, align='center') ax.bar(total2.index.values + 0.2, nochange2 / total2 * 100.0, bottom=(decrease2 / total2 * 100.0), fc='lightgreen', width=0.4, label="%s ''" % (year, ), align='center') ax.bar(total.index.values - 0.2, increase / total * 100.0, bottom=(decrease + nochange) / total * 100.0, fc='r', width=0.4, label="Increase", align='center') ax.bar(total2.index.values + 0.2, increase2 / total2 * 100.0, bottom=(decrease2 + nochange2) / total2 * 100.0, fc='pink', width=0.4, label="%s ''" % (year, ), align='center') offset = -0.2 for _df in [gdf, gyear]: increase = _df[varname + '_greater'] nochange = _df[varname + '_unch'] decrease = _df[varname + '_lower'] total = decrease + nochange + increase for i, _ in _df.iterrows(): txt = ax.text(i + offset, decrease[i] / total[i] * 100.0 - 5, "%.0f" % (decrease[i] / total[i] * 100.0), ha='center', fontsize=10) txt.set_path_effects( [PathEffects.withStroke(linewidth=2, foreground="white")]) ymid = (decrease[i] + (nochange[i] / 2.)) / total[i] * 100. txt = ax.text(i + offset, ymid, "%.0f" % (nochange[i] / total[i] * 100.0), ha='center', va='center', fontsize=10) txt.set_path_effects( [PathEffects.withStroke(linewidth=2, foreground="white")]) txt = ax.text(i + offset, (decrease[i] + nochange[i]) / total[i] * 100.0 + 2, "%.0f" % (increase[i] / total[i] * 100.0), ha='center', fontsize=10) txt.set_path_effects( [PathEffects.withStroke(linewidth=2, foreground="white")]) offset += 0.4 ax.set_xticklabels(calendar.month_abbr[1:]) ax.set_xticks(np.arange(1, 13)) ax.legend(ncol=3, fontsize=12, loc=9, framealpha=1) ax.set_xlim(0.5, 12.5) ax.set_ylim(0, 100) ax.set_yticks([0, 5, 10, 25, 50, 75, 90, 95, 100]) ax.set_ylabel("Percentage of Days [%]") ax.set_xlabel(("Dark Shades are long term averages, lighter are %s " "actuals") % (year, )) ax.set_title(("%s [%s]\nDay to Day %s Temperature Change") % (nt.sts[station]['name'], station, varname.title())) return fig, df
def _plot_ica_sources_evoked(evoked, picks, exclude, title, show, ica, labels=None): """Plot average over epochs in ICA space. Parameters ---------- evoked : instance of mne.Evoked The Evoked to be used. %(picks_base)s all sources in the order as fitted. exclude : array-like of int The components marked for exclusion. If None (default), ICA.exclude will be used. title : str The figure title. show : bool Show figure if True. labels : None | dict The ICA labels attribute. """ import matplotlib.pyplot as plt from matplotlib import patheffects if title is None: title = 'Reconstructed latent sources, time-locked' fig, axes = plt.subplots(1) ax = axes axes = [axes] times = evoked.times * 1e3 # plot unclassified sources and label excluded ones lines = list() texts = list() picks = np.sort(picks) idxs = [picks] if labels is not None: labels_used = [k for k in labels if '/' not in k] exclude_labels = list() for ii in picks: if ii in exclude: line_label = ica._ica_names[ii] if labels is not None: annot = list() for this_label in labels_used: indices = labels[this_label] if ii in indices: annot.append(this_label) line_label += (' - ' + ', '.join(annot)) exclude_labels.append(line_label) else: exclude_labels.append(None) if labels is not None: # compute colors only based on label categories unique_labels = {k.split(' - ')[1] for k in exclude_labels if k} label_colors = plt.cm.rainbow(np.linspace(0, 1, len(unique_labels))) label_colors = dict(zip(unique_labels, label_colors)) else: label_colors = {k: 'red' for k in exclude_labels} for exc_label, ii in zip(exclude_labels, picks): if exc_label is not None: # create look up for color ... if ' - ' in exc_label: key = exc_label.split(' - ')[1] else: key = exc_label color = label_colors[key] # ... but display component number too lines.extend( ax.plot(times, evoked.data[ii].T, picker=3., zorder=2, color=color, label=exc_label)) else: lines.extend( ax.plot(times, evoked.data[ii].T, picker=3., color='k', zorder=1)) ax.set(title=title, xlim=times[[0, -1]], xlabel='Time (ms)', ylabel='(NA)') if len(exclude) > 0: plt.legend(loc='best') tight_layout(fig=fig) # for old matplotlib, we actually need this to have a bounding # box (!), so we have to put some valid text here, change # alpha and path effects later texts.append( ax.text(0, 0, 'blank', zorder=3, verticalalignment='baseline', horizontalalignment='left', fontweight='bold', alpha=0)) # this is done to give the structure of a list of lists of a group of lines # in each subplot lines = [lines] ch_names = evoked.ch_names path_effects = [ patheffects.withStroke(linewidth=2, foreground="w", alpha=0.75) ] params = dict(axes=axes, texts=texts, lines=lines, idxs=idxs, ch_names=ch_names, need_draw=False, path_effects=path_effects) fig.canvas.mpl_connect('pick_event', partial(_butterfly_onpick, params=params)) fig.canvas.mpl_connect('button_press_event', partial(_butterfly_on_button_press, params=params)) plt_show(show) return fig