PyGMT: How to offset focal mechanism beachballs?

Hello again! I am attempting to plot focal mechanism beach-balls and offset them from their point of origin so they don’t overlap, but so far I have been unable to get them to offset. I am aware that a similar issue was reported in March, but am not sure if this is that bug, a different one, or if I’m simply doing it wrong. At present I am attempting to follow the documentation, putting the offset coordinates as the last two columns in the dataframe. However, the beach-balls do not offset from their point of origin.

How can I offset the focal mechanism beachballs?

This is what my dataframe looks like:
Screenshot_2

This is my code:

import pygmt
import pandas as pd
import os

# Main File Path ----------------------------------
main_dir = r'C:\Users\USER\Desktop\FocalMecha'

# Save Path ----------------------------------
save_name = os.path.join(main_dir, 'Results', 'map_A.png')

# Topography Paths ----------------------------------    
grid = os.path.join(main_dir, 'Data', 'ASTER_DEM_merged_EPSG4326-WGS84.tif')

# Focal Mechanism Paths ----------------------------------
focal_mecha = os.path.join(main_dir, 'Data', 'selected_focal_mechanisms.csv')

# Parameters ----------------------------------
region = [-115.85, -115.35, 32.8, 33.38333333333333]

fig = pygmt.Figure()

fig.grdimage(
    grid = grid,
    projection = 'M6i',
    region = region,
    frame = True,
    )

fig.coast(
    shorelines = '0.1p,black',
    resolution = 'f',
    water = 'lightskyblue2',
    )

df_focal_mecha = pd.read_csv(focal_mecha)

pygmt.makecpt(
    cmap="magma", 
    reverse =True,
    series=[df_focal_mecha.depth.min(), df_focal_mecha.depth.max()]
    )

fig.meca(
    spec=df_focal_mecha,
    convention = 'aki',
    scale="1.0c",
    C=True,
    offset = True,
    )

fig.savefig(save_name)

print('done')

@hazardgoat I saw your private message about deleting the post, but I believe the post is good and I think it was accidentally flagged as inappropriate.

Back to your question: yes, it’s a bug of the PyGMT “meca” wrapper, and currently you have to write the mechanism information into a file, and then pass the file the spec, i.e., the following code should work:

fig.meca(
    spec=focal_mecha,
    convention = 'aki',
    scale="1.0c",
    offset = True,
    )
2 Likes

Thank you @seisman. I tried using the file directly instead of a dataframe and when I did no focal mechanisms were plotted at all. I’ve attached the table I’m using for the focal mechanismsselected_focal_mechanisms.txt (397 Bytes) .

The format of the focal mechanism data is incorrect. For a text file input, the columns should be:

lon lat depth strike dip rake magnitude plot_lon plot_y
1 Like

I really do appreciate you helping me with this. I have reordered and renamed my table and while it now plots the focal mechanisms, they still do not offset from their point of origin. The offset column values are just printed above each focal mechanism. I’ve attached my updated table file.selected_focal_mechanisms.txt (418 Bytes)

My output:

The commas in the text file cause the trouble.

An input file like this works:

-115.52666 33.01917 10.11 314 85 -171 5.32 -115.52666 33.17
-115.52783 33.017 8.69 143 87 158 5.44 -115.52783 32.117
-115.6275 33.08567 9.29 158 86 -151 5.75 -115.6275 33.18567
-115.78167 33.08183 8.2 280 86 171 6.2 -115.78167 33.18183
-115.83434 33.01367 5.45 127 72 -159 6.6 -115.83434 33.11367
-115.634 33.14283 5.64 190,62 -106 5.11 -115.634 33.24283
2 Likes

Thank you so much for working through this issue with me! The focal mechanisms offset perfectly now!

Hi,guys,I have met the same problem like you,could you send the new code and data format,thanks very much.

You’ll want to use this code for the fig.meca function if you’re attempting to plot focal mechanisms using the ‘aki’ format and coloring the beach-balls by depth:

SomeDataFrame = pd.read_csv(SomeDataFile, sep='\t')

pygmt.makecpt(
    cmap = 'magma',   # sets the cpt to one of the named built-in ones 
    reverse = True,   # reverse the color scale of the cpt
    series = [SomeDataFrame.SomeColumn.min(), SomeDataFrame.SomeColumn.max()]   # sets the value range by which to assign colors. In this case, by using the min and max values of a column from some dataframe
)

fig.meca(
    spec = SomeDataFile,   # tab separated csv file 
    convention = 'aki',   # convention for columns (strike, dip, rake, magnitude)
    scale = '1.0c',   # size scale in centimeters for the focal mechanism beach-balls
    C = True,   # sets cmap for coloring beach-balls by some column to true
    offset = True,   # sets function to read from the offset columns in the data file
)

The data file must be a tab separated csv file if you want to offset the focal mechanism beach-balls. For the ‘aki’ convention, the column format needs to be in the order of longitude, latitude, depth, strike, dip, rake, magnitude, offset_longitude, offset_latitude, label. You don’t need a label column, but if you choose to have one it will plot the text above each beach-ball. There is however another quirk/bug where the column labels are printed in the very bottom left corner of the map. Removing the column names from the csv file solves this issue.

1 Like