def top_template(): t0 = time() twd = os.path.join(gmt_temp, "top") os.makedirs(twd) t = gmt.GMTPlot("%s/top.ps" % (twd)) gmt.gmt_defaults(wd=twd, ps_media="Custom_%six%si" % (PAGE_WIDTH, PAGE_HEIGHT)) t.spacial( "M", ll_region, sizing=map_width, x_shift=MARGIN_LEFT, y_shift=MARGIN_BOTTOM ) # locations in NZ if ll_region[1] - ll_region[0] > 3: t.sites(gmt.sites_major) else: t.sites(list(gmt.sites.keys())) t.coastlines() # simulation domain t.path(cnr_str, is_file=False, split="-", close=True, width="0.4p", colour="black") # fault path if args.srf is not None: t.fault(args.srf, is_srf=True, plane_width=0.5, top_width=1, hyp_width=0.5) # ticks on top otherwise parts of map border may be drawn over major, minor = gmt.auto_tick(ll_region[0], ll_region[1], map_width) t.ticks(major=major, minor=minor, sides="ws") # render t.finalise() t.png(dpi=args.dpi, clip=False, out_dir=gmt_temp) rmtree(twd) print("top template completed in %.2fs" % (time() - t0))
def test_ticks2(pf): p = gmt.GMTPlot(pf) p.spacial('T', (160.992, 174.9122, -44, -34.01), sizing = 5, \ x_shift = 0.5, y_shift = 0.5, lon0 = 174.9122) p.ticks(major='1d', minor='20m', sides='ew') p.finalise() p.png(dpi=100, clip=True)
def test_fill(pf): p = gmt.GMTPlot(pf) gmt.gmt_defaults(wd=os.path.dirname(pf), ps_media='A5') p.background(1.5, 1) p.background(3, 2, x_margin=1.5, colour='blue') p.background(1.5, 1, y_margin=1, colour='red') p.background(3, 2, x_margin=4.5, colour='firebrick') p.finalise() p.png(dpi=100, clip=False)
def test_cpt(pf): cptf = '%s.cpt' % (os.path.splitext(pf)[0]) gmt.makecpt('hot', cptf, 0, 120, inc = 0.1, invert = True, \ wd = os.path.dirname(pf)) p = gmt.GMTPlot(pf) p.spacial('X', (0, 15, 0, 4), sizing='15/4') p.cpt_scale(6.1, 2.05, cptf, 20, 5, label = 'test_scale', \ length = 3.05, thickness = '0.3i') p.finalise() p.png(dpi=320, clip=True)
def test_cpt2(pf): cptf = '%s.cpt' % (os.path.splitext(pf)[0]) gmt.makecpt('polar', cptf, -1.5, 1.5, inc = 0.25, invert = False, \ wd = os.path.dirname(pf), bg = '0/0/80', fg = '80/0/0') p = gmt.GMTPlot(pf) p.spacial('X', (0, 4, 0, 2), sizing='4/2', x_shift=1, y_shift=1) p.cpt_scale(0, 0, cptf, 0.5, 0.25, cross_tick = 0.5, align = 'LB', \ length = 3, thickness = '0.3i', arrow_f = True, arrow_b = True) p.finalise() p.png(dpi=222, clip=True)
def test_ticks(pf): p = gmt.GMTPlot(pf) p.spacial('M', (160.992, 174.9122, -44, -34.01), sizing=2) p.ticks(major='1d', minor='20m', sides='ew') p.finalise() p.png(dpi=100, clip=True)
def test_land(pf): p = gmt.GMTPlot(pf) p.spacial('M', (170.1, 179.91, -37, -34), sizing=7) p.land(fill='darkred') p.finalise() p.png(dpi=100, clip=True)
def test_coastlines(pf): p = gmt.GMTPlot(pf) p.spacial('M', (170, 175, -44, -38), sizing=3) p.coastlines(width='0.4p') p.finalise() p.png(dpi=200, clip=True)
else: tick_factor = 3 major_tick = 0.05 tick_helper = 0 while km_inch / major_tick > tick_factor: if tick_helper != 2: major_tick *= 2 tick_helper += 1 else: major_tick *= 2.5 tick_helper = 0 # start plot p = gmt.GMTPlot( os.path.join( gmt_temp, f"{os.path.splitext(os.path.basename(args.srf_file))[0]}_slip_rise_rake.ps", )) # override GMT defaults gmt.gmt_defaults( wd=gmt_temp, font_label=label_size, map_tick_length_primary="0.03i", ps_media="A4", font_annot_primary=base_size, ps_page_orientation="landscape", map_frame_pen=f"{scale_factor * 1.5}p,black", ) p.background(media[0], media[1]) # prepare data and CPTs
def bottom_template(): t0 = time() bwd = os.path.join(gmt_temp, "bottom") os.makedirs(bwd) b = gmt.GMTPlot("%s/bottom.ps" % (bwd)) gmt.gmt_defaults(wd=bwd, ps_media="Custom_%six%si" % (PAGE_WIDTH, PAGE_HEIGHT)) if args.borders: b.background(PAGE_WIDTH, PAGE_HEIGHT, colour="white") else: b.spacial("M", borderless_region, sizing=map_width_a) # topo, water, overlay cpt scale b.basemap(land="lightgray", topo_cpt="grey1", resource_region=region_code) # map margins are semi-transparent b.background( map_width_a, map_height_a, colour="white@25", spacial=True, window=(MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM), ) # leave space for left tickmarks and bottom colour scale b.spacial( "M", ll_region, sizing=map_width, x_shift=MARGIN_LEFT, y_shift=MARGIN_BOTTOM ) if args.borders: # topo, water, overlay cpt scale b.basemap(land="lightgray", topo_cpt="grey1", resource_region=region_code) # title, fault model and velocity model subtitles b.text(sum(ll_region[:2]) / 2.0, ll_region[3], args.title, size=20, dy=0.6) b.text(ll_region[0], ll_region[3], args.subtitle1, size=14, align="LB", dy=0.3) b.text( ll_region[0], ll_region[3], args.subtitle2.replace("<HH>", str(xyts.hh)), size=14, align="LB", dy=0.1, ) # cpt scale b.cpt_scale( "R", "B", cpt_file, cpt_inc, cpt_inc, label=args.legend, length=map_height, horiz=False, pos="rel_out", align="LB", thickness=0.3, dx=0.3, arrow_f=cpt_max > 0, arrow_b=cpt_min < 0, ) # stations - split into real and virtual if args.stations is not None: with open(args.stations, "r") as sf: stations = sf.readlines() stations_real = [] stations_virtual = [] for stat in stations: if len(stat.split()[-1]) == 7: stations_virtual.append(stat) else: stations_real.append(stat) b.points( "".join(stations_real), is_file=False, shape="t", size=0.08, fill=None, line="white", line_thickness=0.8, ) b.points( "".join(stations_virtual), is_file=False, shape="c", size=0.02, fill="black", line=None, ) # render b.finalise() b.png(dpi=args.dpi, clip=False, out_dir=gmt_temp) rmtree(bwd) print("bottom template completed in %.2fs" % (time() - t0))
def finish_gs( window_conf, plot_conf, path_conf, vm_conf, gs_file, depth, xyll, vm3d, ): """ Add features specific to current depth plot. """ depth_ix = floor(0.5 + depth / vm_conf["hh"]) if depth_ix >= vm_conf["nz"]: print("skipping depth", depth, "out of range for VM") return depth_value = (0.5 + depth_ix) * vm_conf["hh"] depth_wd = os.path.join(path_conf["gmt_temp"], str(depth)) os.makedirs(depth_wd) depth_gs = f"{depth_wd}/{os.path.basename(path_conf['vm_file']).replace('.', '_')}_{depth}.ps" copyfile(gs_file, depth_gs) for setup in ["gmt.conf", "gmt.history"]: copyfile( os.path.join(path_conf["gmt_temp"], setup), os.path.join(depth_wd, setup) ) p = gmt.GMTPlot(depth_gs, append=True, reset=False) xyz_bin = os.path.join(depth_wd, "xyz.bin") surface = np.column_stack((xyll.reshape(-1, 2), vm3d[:, depth_ix, :].flatten())) surface.astype(np.float32).tofile(xyz_bin) cpt_inc, cpt_max = gmt.xyv_cpt_range(xyz_bin)[1:3] cpt_file = os.path.join(depth_wd, "cpt.cpt") cpt_min = 0 # colour scale gmt.makecpt( plot_conf["cpt"], cpt_file, cpt_min, cpt_max, continuous=True, invert=plot_conf["cpt_invert"], bg=None, fg=None, ) p.clip(path=plot_conf["corners_gmt"]) spacing = f"{vm_conf['hh'] * 0.4}k" p.overlay( xyz_bin, cpt_file, dx=spacing, dy=spacing, custom_region=plot_conf["ll_region_data"], ) p.clip() p.text( window_conf["ll_region"][1], window_conf["ll_region"][3], f"depth: {depth_value:.2f}km", size=14, align="RB", dy=0.1, ) p.cpt_scale( "R", "B", cpt_file, cpt_inc, cpt_inc, label=plot_conf["legend"], length=window_conf["map_height"], horiz=False, pos="rel_out", align="LB", thickness=0.3, dx=0.3, arrow_f=cpt_max > 0, arrow_b=cpt_min < 0, ) p.path(plot_conf["corners_gmt"], is_file=False, close=True, width="1p", split="-") # ticks on top otherwise parts of map border may be drawn over major, minor = gmt.auto_tick( *window_conf["ll_region"][0:2], window_conf["map_width"] ) p.ticks(major=major, minor=minor, sides="ws") # render p.finalise() p.png( dpi=window_conf["dpi"] * window_conf["downscale"], downscale=window_conf["downscale"], clip=False, out_dir=path_conf["out_dir"], )
def template_gs(window_conf, path_conf): """ Create the common background plot. """ gs_file = "%s/template.ps" % (path_conf["gmt_temp"]) p = gmt.GMTPlot(gs_file) gmt.gmt_defaults( wd=path_conf["gmt_temp"], ps_media="Custom_%six%si" % (window_conf["page_width"], window_conf["page_height"]), ) if window_conf["borders"]: p.background( window_conf["page_width"], window_conf["page_height"], colour="white" ) else: # extend map to cover margins map_width_a, map_height_a, borderless_region = gmt.fill_margins( window_conf["ll_region"], window_conf["map_width"], window_conf["dpi"], left=MARGIN_LEFT, right=MARGIN_RIGHT, top=MARGIN_TOP, bottom=MARGIN_BOTTOM, ) p.spacial("M", borderless_region, sizing=map_width_a) # topo, water, overlay cpt scale p.basemap(land="lightgray", topo_cpt="grey1", scale=window_conf["downscale"]) # map margins are semi-transparent p.background( map_width_a, map_height_a, colour="white@25", spacial=True, window=(MARGIN_LEFT, MARGIN_RIGHT, MARGIN_TOP, MARGIN_BOTTOM), ) # leave space for left tickmarks and bottom colour scale p.spacial( "M", window_conf["ll_region"], sizing=window_conf["map_width"], x_shift=MARGIN_LEFT, y_shift=MARGIN_BOTTOM, ) if window_conf["borders"]: # topo, water, overlay cpt scale p.basemap(land="lightgray", topo_cpt="grey1", scale=window_conf["downscale"]) # title, fault model and velocity model subtitles p.text( sum(window_conf["ll_region"][:2]) / 2.0, window_conf["ll_region"][3], "Velocity Model", size=20, dy=0.6, ) p.text( window_conf["ll_region"][0], window_conf["ll_region"][3], f"NZVM v{vm_conf['model_version']} h={vm_conf['hh']}km", size=14, align="LB", dy=0.3, ) p.text( window_conf["ll_region"][0], window_conf["ll_region"][3], os.path.basename(path_conf["vm_file"]), size=14, align="LB", dy=0.1, ) p.leave() return gs_file
def slip_sequence(frame): # working directory for this process pwd = os.path.join(gwd, f"ss{frame:04}") if not os.path.exists(pwd): os.makedirs(pwd) ps_file = os.path.join( pwd, f"seq_{zoom_frames - zoom_frames * draft + frame}.ps") copyfile(os.path.join(gwd, "basemap.ps"), ps_file) copyfile(os.path.join(gwd, "gmt.conf"), os.path.join(pwd, "gmt.conf")) copyfile(os.path.join(gwd, "gmt.history"), os.path.join(pwd, "gmt.history")) # finish plot s = gmt.GMTPlot(ps_file, append=True, reset=False) # current time s.text( region_srf[1], region_srf[3], f"t = {frame * ftime}s", dx=0.5, dy=0.2, align="LB", size="16p", ) # prepare overlays for plane in range(len(srf_bounds)): plane_data = np.empty((len(slip_pos[plane]), 3)) plane_data[:, :2] = slip_pos[plane] plane_data[:, 2] = slip_rate[plane][:, frame] # do not plot if all values are nan (no data at this time in plane) if np.min(np.isnan(plane_data[:, 2])): continue xyv_file = os.path.join(pwd, f"plane_{plane}.bin") plane_data.astype(np.float32).tofile(xyv_file) gmt.table2grd( xyv_file, f"{xyv_file}.grd", grd_type="nearneighbor", sectors=1, min_sectors=1, region=plane_regions[plane], dx=plot_dx, dy=plot_dy, wd=pwd, search=f"{srf_dx}k", ) s.overlay( f"{xyv_file}.grd", cpt_sliprate, dx=plot_dx, dy=plot_dy, climit=0.5, crop_grd=os.path.join(gwd, f"plane_{plane}.mask"), land_crop=False, custom_region=plane_regions[plane], transparency=0, ) if draft: s.coastlines(width=0.2, res="f") else: s.coastlines(width=0.2) # TODO: fault thickness must be related to zfactor used during zoom s.fault(srf_corners, is_srf=False, plane_width="1", hyp_width="1", top_width="2") s.ticks(major=tick_major, minor=tick_minor) s.finalise() s.png(dpi=dpi, out_dir=out, clip=False) print(f"Slip sequence {frame + 1:03}/{srf_frames:03} complete.")
def zoom_sequence(frame): # working directory for this process pwd = os.path.join(gwd, f"zs{frame:04}") if not os.path.exists(pwd): os.makedirs(pwd) ps_file = os.path.join(pwd, f"seq_{frame:04}.ps") copyfile(os.path.join(gwd, "gmt.conf"), os.path.join(pwd, "gmt.conf")) z = gmt.GMTPlot(ps_file, reset=False) plot_region, plot_width, x_margin, y_margin = gmt.region_transition( "M", region_nz, region_srf, map_width, map_height, dpi, frame, zoom_frames, wd=pwd, ) # extend map to cover margins map_width_a, map_height_a, borderless_region = gmt.fill_margins( plot_region, plot_width, dpi, left=margin_left + x_margin, right=margin_right + x_margin, top=margin_top + y_margin, bottom=margin_bottom + y_margin, wd=pwd, ) z.spacial("M", borderless_region, sizing=map_width_a) # topo, water, overlay cpt scale z.basemap() # map margins are semi-transparent z.background( map_width_a, map_height_a, colour="white@25", spacial=True, window=( margin_left + x_margin, margin_right + x_margin, margin_top + y_margin, margin_bottom + y_margin, ), ) # leave space for left tickmarks and bottom colour scale z.spacial( "M", plot_region, sizing=plot_width, x_shift=margin_left + x_margin, y_shift=margin_bottom + y_margin, ) # title is SRF name z.text( sum(plot_region[:2]) / 2.0, plot_region[3], os.path.basename(srf_file), dy=0.2, align="CB", size="20p", ) # for scaling fault line thickness zfactor = (region_srf[1] - region_srf[0]) / (plot_region[1] - plot_region[0]) z.fault( srf_corners, is_srf=False, top_width=zfactor * 2.4, plane_width=zfactor * 1.2, hyp_width=zfactor * 1.2, ) tick_major, tick_minor = gmt.auto_tick(plot_region[0], plot_region[1], plot_width) z.ticks(major=tick_major, minor=tick_minor) z.finalise() z.png(dpi=dpi, out_dir=out, clip=False) print(f"Opening zoom sequence {frame + 1:03}/{zoom_frames:03} complete.")
spec_sr = f"sliprate-{ftime}-{srf_frames * ftime}" slip_pos, slip_rate = srf.srf2llv_py(srf_file, value=spec_sr) # produce the max sliprate array for colour palette and stats sliprate_max = np.array([], dtype=np.float32) for plane in range(len(slip_rate)): sliprate_max = np.append(sliprate_max, np.nanmax(slip_rate[plane], axis=1)) # maximum range to 2 sf cpt_max = np.nanpercentile(sliprate_max, 50) cpt_max = round(cpt_max, 1 - int(floor(log10(abs(cpt_max))))) print("Time series processed.") # colour palette for slip cpt_sliprate = os.path.join(gwd, "sliprate.cpt") gmt.makecpt(gmt.CPTS["slip"], cpt_sliprate, 0, cpt_max, inc=2, invert=False) # create basemap b = gmt.GMTPlot(os.path.join(gwd, "basemap.ps"), reset=False) if not draft: # extend map to cover margins map_width_a, map_height_a, borderless_region = gmt.fill_margins( region_srf, map_width, dpi, left=margin_left, right=margin_right, top=margin_top, bottom=margin_bottom, ) b.spacial("M", borderless_region, sizing=map_width_a) # topo, water, overlay cpt scale b.basemap() # map margins are semi-transparent
def render_slice(n): t0 = time() # process working directory swd = "%s/ts%.4d" % (gmt_temp, n) os.makedirs(swd) s = gmt.GMTPlot("%s/ts%.4d.ps" % (swd, n), reset=False) gmt.gmt_defaults(wd=swd, ps_media="Custom_%six%si" % (PAGE_WIDTH, PAGE_HEIGHT)) s.spacial( "M", ll_region, sizing=map_width, x_shift=MARGIN_LEFT, y_shift=MARGIN_BOTTOM ) # timestamp text s.text( ll_region[1], ll_region[3], "t=%.2fs" % (n * xyts.dt), align="RB", size="14p", dy=0.1, ) # overlay if args.xyts2 is None: xyts.tslice_get(n, comp=-1, outfile="%s/ts.bin" % (swd)) else: x1 = xyts.tslice_get(n, comp=-1) x2 = xyts2.tslice_get(n, comp=-1) x2[:, 2] -= x1[:, 2] x2.astype(np.float32).tofile(os.path.join(swd, "ts.bin")) s.clip(cnr_str, is_file=False) if args.land_crop: s.clip(gmt.regional_resource("NZ", resource="coastline"), is_file=True) gmt.table2grd( os.path.join(swd, "ts.bin"), os.path.join(swd, "ts.grd"), dx=grd_dxy, wd=swd, climit=convergence_limit, ) s.overlay( os.path.join(swd, "ts.grd"), cpt_file, dx=grd_dxy, dy=grd_dxy, min_v=lowcut, max_v=highcut, contours=cpt_inc, ) s.clip() # add seismograms if wanted if args.seis is not None: # TODO: if used again, look into storing params inside seismo file s.seismo(os.path.abspath(args.seis), n, fmt="time", colour="red", width="1p") # create PNG s.finalise() s.png(dpi=args.dpi, clip=False, out_dir=png_dir) # cleanup rmtree(swd) print("timeslice %.4d completed in %.2fs" % (n, time() - t0))
cpt_depth_max, 0.1, invert=False, bg="white", fg="77/0/1", ) gmt.gmt_defaults(wd=gmt_tmp) # gap on left of maps gap = 1 # width of the region map, if changed, other things also need updating # including tick font size and or tick increment for that map full_width = 4 ### PART A: zoomed in map p = gmt.GMTPlot( "%s/%s_map.ps" % (gmt_tmp, os.path.splitext(os.path.basename(args.srf_file))[0])) # this is how high the region map will end up being full_height = gmt.mapproject( region_corners[0], region_corners[3], region=region_corners, projection="M%s" % (full_width), wd=gmt_tmp, )[1] # match height of zoomed in map with full size map zoom_width, zoom_height = gmt.map_width("M", full_height, plot_region, wd=gmt_tmp) p.spacial("M", plot_region, sizing=zoom_width, x_shift=gap, y_shift=2.5)
import numpy as np from qcore import gmt corners = pkg_resources.resource_filename("visualization", "data/SimAtlasFaults.csv") balls = pkg_resources.resource_filename("visualization", "data/gmt.bb") mom2mag = lambda mom: (2 / 3.0 * math.log(mom) / math.log(10.0)) - 10.7 parser = ArgumentParser() arg = parser.add_argument arg("lat", help="Latitude", type=float) arg("lon", help="Longitude", type=float) args = parser.parse_args() p = gmt.GMTPlot("proximity_plot.ps") # in a future release of GMT, this might be possible # p.spacial("M" + str(args.lon) + "/" + str(args.lat) + "/", ("-200", "200", "-200", "200+uk"), sizing=8, x_shift=2, y_shift=2) p.spacial( "M", (args.lon - 1.3, args.lon + 1.3, args.lat - 1, args.lat + 1), sizing=8, x_shift=1, y_shift=1, ) p.basemap() paths = [] with open(corners, "r") as c: c.readline() for l in c: