Result visualization
Make sure the Python module Pygmt is loaded.
This part plot the output files for result visualization. Users can directly run the following codes to plot the results automatically.
python plot_output.py
Figures are output as img/imaging_result.png
Here we demonstrate the plotting script step-by-step
1. Load necessary Python modules
import pygmt
pygmt.config(FONT="16p", IO_SEGMENT_MARKER="<<<")
import os
from pytomoatt.model import ATTModel
from pytomoatt.data import ATTData
import numpy as np
import sys
sys.path.append('../utils')
import functions_for_data as ffd
2. Read models
We read the initial and final models.
# read model files
Ngrid = [121,121,121]
data_file = '2_models/model_init_N%d_%d_%d.h5'%(Ngrid[0],Ngrid[1],Ngrid[2])
par_file = '3_input_params/input_params_real.yaml'
model = ATTModel.read(data_file, par_file)
init_model = model.to_xarray()
data_file = 'OUTPUT_FILES/OUTPUT_FILES_real/final_model.h5'
model = ATTModel.read(data_file, par_file)
inv_model = model.to_xarray()
3. Read earthquake and station locations
ev, st = ffd.read_src_rec_file('1_src_rec_files/src_rec_file.dat')
# earthquake location
ev_lon, ev_lat, ev_dep , _ = ffd.data_lon_lat_dep_wt_ev(ev)
# station location
st_lon, st_lat, _, _ = ffd.data_lon_lat_ele_wt_st(ev,st)
4. Load topography
# load topography
region = [97,106,12,21]
grid_topo = pygmt.datasets.load_earth_relief(resolution="01m", region=region)
grid_gra = pygmt.grdgradient(grid = grid_topo, azimuth = 0)
# %%
def line_read(file):
doc=open(file,'r')
file = doc.readlines()
doc.close()
lat = []; lon = [];
for info in file:
tmp = info.split()
lon.append(float(tmp[0]))
lat.append(float(tmp[1]))
return((lat,lon))
5. Plot the map in the top left panel.
fig = pygmt.Figure()
try:
os.mkdir("img")
except:
pass
# ------------------ Sub fig 1. topography ------------------
region = [97,106,12,21]
projection = "B101.5/16.5/12/21/10c"
frame = ["xa2+lLongitude", "ya2+lLatitude", "nSWe"]
spacing = [0.1, 0.1]
# topography
pygmt.makecpt(cmap="globe", series=[-4000,4000], background = True)
fig.grdimage(grid=grid_topo, shading = grid_gra, projection=projection, frame=frame,region=region)
# station
fig.plot(x = st_lon, y = st_lat, style = "t0.4c", fill = "blue", pen = "1p,white", label = "Station")
# tectonic setting
(lat,lon) = line_read('tectonics/Khorat_new.txt') # Khorat Plateau
fig.plot(x = lon, y = lat, pen = "1p,black")
fig.text(text = "Khorat", x = 103.5, y = 17.5, font = "15p,Helvetica-Bold,black", angle = 0)
fig.text(text = "Plateau", x = 103.5, y = 16.5, font = "15p,Helvetica-Bold,black", angle = 0)
(lat,lon) = line_read('tectonics/WangChaoFault.txt') # Wang-Chao Fault
fig.plot(x = lon, y = lat, pen = "1p,black,-")
fig.text(text = "WCF", x = 100, y = 16, font = "20p,Helvetica-Bold,white=1p", angle = 315)
(lat,lon) = line_read('tectonics/3PagodasFault.txt') # Three Pagodas Fault
fig.plot(x = lon, y = lat, pen = "1p,black,-")
fig.text(text = "TPF", x = 98.5, y = 14.5, font = "20p,Helvetica-Bold,white=1p", angle = 315)
(lat,lon) = line_read('tectonics/DBPF.txt') # Dien Bien Phu Fault
fig.plot(x = lon, y = lat, pen = "1p,black,-")
fig.text(text = "DBPF", x = 102, y = 19.5, font = "20p,Helvetica-Bold,white=1p", angle = 55)
(lat,lon) = line_read('tectonics/SongMaSuture.txt') # Song Ma Suture
fig.plot(x = lon, y = lat, pen = "1p,black,-")
fig.text(text = "Shan-Thai", x = 99, y = 20, font = "18p,Helvetica-Bold,black=0.5p,white", angle = 0)
fig.text(text = "Block", x = 99, y = 19.3, font = "18p,Helvetica-Bold,black=0.5p,white", angle = 0)
fig.text(text = "Indochina Block", x = 103.5, y = 15, font = "18p,Helvetica-Bold,black=0.5p,white", angle = 315)
fig.shift_origin(xshift= 1, yshift=-1.5)
fig.colorbar(frame = ["a%f"%(4000),"y+lElevation (m)"], position="+w4c/0.3c+h")
fig.shift_origin(xshift=-1, yshift=+1.5)
fig.shift_origin(xshift=0, yshift=-13)
6. Plot earthquake distributions in the bottom left panel
# ------------------ Sub fig 2. earthquakes ------------------
region = "g"
projection = "E101/16/90/10c" # centerlon/centerlat/distnace_range/fig_size
frame = ["ya180"]
spacing = [0.1, 5]
fig.basemap(region=region, projection=projection, frame=frame)
fig.coast(region=region, projection=projection, frame=frame, water="white", land="gray", A=10000)
fig.plot(x=101.5, y=16.5, pen="1p,black,-", style="E-60d")
fig.plot(x=101.5, y=16.5, pen="1p,black,-", style="E-120d")
fig.plot(x=101.5, y=16.5, pen="1p,black,-", style="E-180d")
fig.text(x = [101.5, 101.5, 101.5], y = [-8.0, -38.0, -68], text = ['30', '60', '90'], font="13p")
fig.plot(x=[97,97,106,106,97], y=[11,21,21,11,11], pen="1p,red")
pygmt.makecpt(cmap="jet", series=[0, 100], background=True)
fig.plot(x = ev_lon, y = ev_lat, size = [0.4]*len(ev_lon), fill = ev_dep, style = "a", cmap = True, pen = "0.5p,white")
fig.shift_origin(xshift= 1, yshift=-1)
fig.colorbar(frame = ["a%f"%(50),"y+lFocal depth (km)"], position="+w4c/0.3c+h")
fig.shift_origin(xshift=-1, yshift=+1)
fig.shift_origin(xshift= 13, yshift= 13)
7. Plot velocity perturbation profiles
We illustrate the tomographic images via:
- Four horizontla profiles at 100 km, 200 km, 300 km, and 400 km depth;
- Three vertical profiles AA’, BB’, and CC’.
# ------------------ Sub fig 3. model ------------------
# ------------------ Sub fig 3. depth and vertical profile ------------------
region = [97,106,12,21]
projection = "B101.5/16.5/12/21/10c"
frame = ["xa2+lLongitude", "ya2+lLatitude", "nSWe"]
spacing = [0.1, 0.1]
depth_list = [100,200,300,400]
start_list = [ [97, 19], [97, 17.2], [101.8, 12] ]
end_list = [ [106, 15], [106, 13.2], [101.8, 21] ]
# depth profiles
for idepth, depth in enumerate(depth_list):
# read models
vel_init = init_model.interp_dep(depth, field='vel')
vel_inv = inv_model.interp_dep(depth, field='vel')
if idepth == 3:
fig.shift_origin(xshift=-39, yshift=-13)
pygmt.makecpt(cmap="../utils/svel13_chen.cpt", series=[-2, 2], background=True)
x = vel_inv[:,0]; y = vel_inv[:,1]; value = (vel_inv[:,2] - vel_init[:,2])/vel_init[:,2]*100
grid = pygmt.surface(x=x, y=y, z=value, spacing=spacing,region=region)
fig.grdimage(frame=frame,grid = grid,projection=projection, region=region) # nan_transparent may work
(lat,lon) = line_read('tectonics/Khorat_new.txt') # Khorat Plateau
fig.plot(x = lon, y = lat, pen = "1p,black")
# vertical profile location
fig.plot(x = [start_list[0][0],end_list[0][0]], y = [start_list[0][1],end_list[0][1],], pen = "2p,green,-")
fig.text(text = "A", x = start_list[0][0] + 0.5, y = start_list[0][1], font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
fig.text(text = "A@+'@+", x = end_list[0][0] - 0.5, y = end_list[0][1] + 0.5, font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
fig.plot(x = [start_list[1][0],end_list[1][0]], y = [start_list[1][1],end_list[1][1],], pen = "2p,green,-")
fig.text(text = "B", x = start_list[1][0] + 0.5, y = start_list[1][1], font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
fig.text(text = "B@+'@+", x = end_list[1][0] - 0.5, y = end_list[1][1] + 0.5, font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
fig.plot(x = [start_list[2][0],end_list[2][0]], y = [start_list[2][1],end_list[2][1],], pen = "2p,green,-")
fig.text(text = "C", x = start_list[2][0] - 0.5, y = start_list[2][1] + 0.5, font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
fig.text(text = "C@+'@+", x = end_list[2][0] - 0.5, y = end_list[2][1] - 0.5, font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
# depth label
fig.text(text="%d km"%(depth), x = 98 , y = 12.5, font = "14p,Helvetica-Bold,black", fill = "white")
fig.shift_origin(xshift=13)
fig.shift_origin(yshift=6)
# vertical profiles
for iprof in range(len(start_list)):
# generate topography data
Npoints = 100
point_x = np.linspace(start_list[iprof][0],end_list[iprof][0],Npoints)
point_y = np.linspace(start_list[iprof][1],end_list[iprof][1],Npoints)
points = np.hstack((point_x.reshape(-1,1),point_y.reshape(-1,1)))
topo = np.array(pygmt.grdtrack(points=points, grid=grid_topo)[2])
topo_dis = [0]
for ip in range(1, Npoints):
dis = ffd.cal_dis(point_y[0], point_x[0], point_y[ip], point_x[ip])
topo_dis.append(dis)
topo_dis = np.array(topo_dis)
# read models
vel_init_sec = init_model.interp_sec(start_list[iprof], end_list[iprof], field='vel', val=10)
vel_inv_sec = inv_model.interp_sec(start_list[iprof], end_list[iprof], field='vel', val=10)
# plot topography
max_dis = np.max(vel_init_sec[:,2])
region = [0,max_dis,0,2000]
projection = "X%f/1c"%(max_dis/400*4)
frame = ["ya2000+lElevation (m)", "sW"]
fig.shift_origin(yshift=4)
fig.basemap(region=region, projection=projection, frame=frame)
fig.plot(x = topo_dis, y = topo, pen = "1p,black", frame = frame, projection = projection, region = region)
fig.shift_origin(yshift=-4)
# plot model
region = [0,max_dis,0,400]
projection = "X%f/-4c"%(max_dis/400*4)
frame = ["xa300+lDistance (km)", "ya100+lDepth (km)", "nSWe"]
spacing = [10, 5]
x_sec = vel_inv_sec[:,2]; y_sec = vel_inv_sec[:,3]; value_sec = (vel_inv_sec[:,4] - vel_init_sec[:,4])/vel_init_sec[:,4]*100
grid = pygmt.surface(x=x_sec, y=y_sec, z=value_sec, spacing=spacing,region=region)
fig.grdimage(frame=frame,grid = grid,projection=projection, region=region) # nan_transparent may work
label_list = ['A', 'B', 'C']
fig.text(text = "%s"%(label_list[iprof]), x = 50, y = 50 , font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
fig.text(text = "%s@+'@+"%(label_list[iprof]), x = np.max(x) - 50, y = 50, font = "18p,Helvetica-Bold,black", fill = "lightblue", angle = 0)
if (iprof == 0):
fig.shift_origin(xshift=0, yshift=-6.5)
elif (iprof == 1):
fig.shift_origin(xshift=13, yshift=6.5)
fig.shift_origin(xshift= 2, yshift=-2.5)
fig.colorbar(frame = ["a%f"%(2),"y+ldlnVp (%)"], position="+w4c/0.3c+h")
fig.shift_origin(xshift=-2, yshift=+2.5)
fig.show()
fig.savefig("img/imaging_result.png")
Last updated on