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:

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()

    grid = grid,
    projection = 'M6i',
    region = region,
    frame = True,

    shorelines = '0.1p,black',
    resolution = 'f',
    water = 'lightskyblue2',

df_focal_mecha = pd.read_csv(focal_mecha)

    reverse =True,
    series=[df_focal_mecha.depth.min(), df_focal_mecha.depth.max()]

    convention = 'aki',
    offset = True,



@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:

    convention = 'aki',
    offset = True,

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

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')

    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

    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

After many trials, I can plot this map, but it still can’t get the offset to avoid overlapping. Can anyone help me?

Can we get the map like this using PyGMT? Thank you.

What version of PyGMT are you using?

This example may be what you’re looking for.

1 Like

Thank you for the response. I use PyGMT 0.5.0. Finally, I made it. I used the data in .dat format, and it worked very well. But can you help me to make a text for the beachball?


1 Like

whats problem this error???

Hello Guys
I have Problem about plot focal mechanisem offset in Pygmt:
may be you can help me something

my script python below:

import pygmt
import pandas as pd

#Read Data
data = pd.read_csv(‘eq_data_sulut-focmech2.csv’)
minlon, maxlon = 117.4,130
minlat, maxlat = -4.0,8
region = [minlon,maxlon,minlat,maxlat]

#Plot coast

fig = pygmt.Figure()
frame = ‘ag’,

#Plot Data Focal Mechanisme
scale =‘0.3c’,
frame = True)

#Convert file ke PNG
fig.savefig (“focmech_sulut2.png”, crop=True, dpi=500, transparent=True)