def onclick(event): if event.inaxes != None: xpx = event.xdata ypx = event.ydata try: out = (xpx, ypx, gbma[ypx, xpx]) if ggt is not None: #Note matplotlib (0,0) is lower left #gdal (0,0) is upper left mx, my = geolib.pixelToMap(xpx, ypx, ggt) out = (xpx, ypx), (mx, my, gbma[ypx, xpx]) print out except IndexError: pass
def plot_point(ex, ey): if ex > m.shape[2]-1 or ey > m.shape[1]-1: print "Input coordinates are outside stack extent:" print ex, ey print m.shape else: v = sample_stack(ex, ey, geoid_offset=geoid_offset, pad=pad) v_idx = (~np.ma.getmaskarray(v)).nonzero()[0] v_error = error[v_idx].data v_source = source[v_idx].data samp_list = split_sample(v) #v = m[:,ey,ex] #if not samp_list: if v.count() > 0: c = next(colors) v_mean = v.mean() v_valid = v.compressed() v_rel_valid = v_valid - v_mean d_valid = np.ma.array(d, mask=np.ma.getmaskarray(v)).compressed() #Plot trendline if plot_trend: vm, r, slope = linregress(v) vm_rel = vm - v_mean plt.figure(1) ax_rel.plot_date(d, vm_rel, label='%0.1f m/yr' % slope, marker=None, markersize=ms, color=c, linestyle='--', linewidth=0.6) #v_rel_abs_lim = int(max(abs(v_rel.min()), abs(v_rel.max())) + 0.5) #if np.all(np.abs(ax_rel.get_ylim()) < vn_abs_lim): # ax_rel.set_ylim(-v_rel_abs_lim, v_rel_abs_lim) if plot_resid: plt.figure(3) r_samp_list = split_sample(r) for i in r_samp_list: r_line, = ax_resid.plot_date(i[0], i[1], marker=i[4], alpha=i[5], markersize=ms, color=c, linestyle='None') if errorbars: if np.any(i[2] != 0): ax_resid.errorbar(i[0], i[1], yerr=i[2], color=c, linestyle='None') plt.draw() for i in samp_list: #Don't label, as we want legend to contain trend values plt.figure(1) v_rel_line, = ax_rel.plot_date(i[0], i[1]-v_mean, marker=i[4], alpha=i[5], markersize=ms, color=c, linestyle='None') if errorbars: if np.any(i[2] != 0): plt.figure(1) ax_rel.errorbar(i[0], i[1]-v_mean, yerr=i[2], color=c, linestyle='None') plt.figure(2) v_line, = ax_abs.plot_date(i[0], i[1], marker=i[4], alpha=i[5], markersize=ms, color=c, linestyle='None') if errorbars: if np.any(i[2] != 0): plt.figure(2) ax_abs.errorbar(i[0], i[1], yerr=i[2], color=c, linestyle='None') plt.figure(2) #Now draw lines connecting points v_line, = ax_abs.plot_date(d_valid, v_valid, marker=None, color=c, linestyle='-', linewidth=0.6, alpha=0.5) plt.draw() #Don't really need/want lines between points on this one - too busy plt.figure(1) v_rel_line, = ax_rel.plot_date(d_valid, v_rel_valid, marker=None, color=c, linestyle='-', linewidth=0.6, alpha=0.5) if plot_trend: #Add legend containing trend values plt.legend(loc='upper right', prop={'size':10}) plt.draw() #Plot doy #Need to add title to doy plots mx, my = geolib.pixelToMap(ex, ey, gt) title='%0.1f, %0.1f' % (mx, my) #doy_plot(s.date_list, v, ylabel, title=title) #create_legend_interactive(ax_abs) #Now add point to context maps plt.figure(0) #Could get fancy here and scale the marker as unfilled square scaled to size of padded sample ax_pt_list[0].extend(ax_list[0].plot(ex, ey, 'o', color=c)) ax_pt_list[1].extend(ax_list[1].plot(ex, ey, 'o', color=c)) ax_pt_list[2].extend(ax_list[2].plot(ex, ey, 'o', color=c)) ax_pt_list[3].extend(ax_list[3].plot(ex, ey, 'o', color=c)) plt.draw() if False: out_fn = 'stack_sample_%0.1f_%0.1f.csv' % (mx, my) #np.savetxt(out_fn, np.array([d_valid, v_valid, v_error, v_source]).T, fmt='%0.6f, %0.1f, %0.1f, %s', delimiter=',') np.savetxt(out_fn, np.array([d_valid, v_valid, v_error]).T, fmt='%0.6f, %0.1f, %0.1f', delimiter=',')
def sample_stack(ex, ey, geoid_offset=False, pad=3): if ex > m.shape[2]-1 or ey > m.shape[1]-1: print "Input coordinates are outside stack extent:" print ex, ey print m.shape v = None else: print "Sampling with pad: %i" % pad if pad == 0: v = m[:,ey,ex] else: window_x = np.around(np.clip([ex-pad, ex+pad+1], 0, m.shape[2]-1)).astype(int) window_y = np.around(np.clip([ey-pad, ey+pad+1], 0, m.shape[1]-1)).astype(int) print window_x print window_y v = m[:,window_y[0]:window_y[1],window_x[0]:window_x[1]].reshape(m.shape[0], np.ptp(window_x)*np.ptp(window_y)) #v = v.mean(axis=1) v = np.ma.median(v, axis=1) if v.count() == 0: print "No valid values" else: mx, my = geolib.pixelToMap(ex, ey, gt) print ex, ey, mx, my print "Count: %i" % v.count() #Hack to get elevations relative to geoid #Note: this can be added multiple times if clicked quickly if geoid_offset: #geoid_offset = geolib.sps2geoid(mx, my, 0.0)[2] geoid_offset = geolib.nps2geoid(mx, my, 0.0)[2] print "Removing geoid offset: %0.1f" % geoid_offset v += geoid_offset #Should filter here #RS1 has some values that are many 1000s of m/yr below neighbors if filter_outliers: if True: med = malib.fast_median(v) mad = malib.mad(v) min_v = med - mad*4 f_idx = (v < min_v).filled(False) if np.any(f_idx): print med, mad print "Outliers removed by absolute filter: (val < %0.1f)" % min_v print timelib.o2dt(d[f_idx]) print v[f_idx] v[f_idx] = np.ma.masked if True: v_idx = (~np.ma.getmaskarray(v)).nonzero()[0] #This tries to maintain fixed window in time f = filtlib.rolling_fltr(v, size=7) #This uses fixed number of neighbors f = filtlib.rolling_fltr(v[v_idx], size=7) #f_diff = np.abs(f - v) #Note: the issue is usually that the velocity values are too low #f_diff = f - v f_diff = f - v[v_idx] diff_thresh = 2000 #f_idx = (f_diff > diff_thresh).filled(False) #f_idx = (f_diff < diff_thresh).filled(False) f_idx = np.zeros_like(v.data).astype(bool) f_idx[v_idx] = (f_diff > diff_thresh) if np.any(f_idx): print "Outliers removed by rolling median filter: (val < %0.1f)" % diff_thresh print timelib.o2dt(d[f_idx]) print v[f_idx] v[f_idx] = np.ma.masked return v