Change the color of a focal mechanism by magnitude rather than depth using a PSMECA spec file

Hello! I’m currently plotting some focal mechanisms on a map, and they all fall within a relatively small magnitude range so just the size of the focal mechanism scaling by magnitude isn’t quite as distinctive as I’d like. I want to change the compressive fill color of each focal mechanism by magnitude. However, I’m using a PSMECA file from SPUD and convention = ‘mt’ to plot the focal mechanisms, and it seems from the documentation (and my screwing around) that using the cmap command will only work to choose colors based on the depth, since that’s the third column in the PSMECA file. Is there a way to change the color by magnitude instead, or would I need to do this a different way (maybe without using the PSMECA file)?

Here are the relevant parts of my code, where I currently am coloring the focal mechanisms by depth. I have made a CPT for the magnitude range the same way as I did for the depths here (using a different file since the PSMECA format doesn’t have an explicit moment magnitude column), and would ideally like to use that as the cmap for the focal mechanisms instead of this depth one if possible.

# Use depth column from PSMECA file to make a cpt
psmeca = np.genfromtxt(psmeca_file, dtype = float)
psmeca_depths = psmeca[:,2]
pygmt.makecpt(cmap='viridis', series=[psmeca_depths.min(), psmeca_depths.max()], output = path + 'depth_cpt.cpt')

fig = pygmt.Figure()
region=[-133,-108,28,53]
fig.coast(region=region, projection='N12c', land='wheat3', water='lightcyan2', frame='afg')
fig.meca(spec = psmeca_file, convention = 'mt', scale = '0.6c', cmap = path + 'depth_cpt.cpt')
fig.show();

Hello @sdybing,

Welcome to the GMT forum :slightly_smiling_face:!

It’s correct, that the color-coding of the beachballs relies on the event depth column or the third column for an input file.

A workaround for a color-coding based on another quantity can be to have these values in the event depth column or the third column.

For your use case

  • You can try combining the two files, so that the moment magnitude values are in the third column.

OR

  • You can try loading both files into pandas Dataframes (or creating dictionaries) and then combing them into one Dataframe (dictionary), whereby the column called depth contains actually (again) the moment magnitude values. For all column names depending on the convention, please see the documentation at pygmt.Figure.meca — PyGMT
import pygmt

size = 5

# Create some foacal mechanism data based on the Aki convention
fm_collection = {
    "strike": [166, 166, 166, 166],
    "dip": [80, 80, 80, 80],
    "rake": [74, 74, 74, 74],
    "magnitude": [2, 4, 5, 8],
    "depth": [2, 4, 5, 8],  # Give the values of the magntiude as depth
    "longitude": [-4, -3, 0, 2],
    "latitude": [-3, 2, 1, 3],
}

# Create a new Figure instance
fig = pygmt.Figure()
fig.basemap(region=[-size, size, -size, size], projection=f"X{size}c", frame=True)

# Set up a colormap for the moment magnitude (linear)
pygmt.makecpt(cmap="lajolla", series=[0, 10, 0.1])
# Plot the focal mechanisms
fig.meca(
    spec=fm_collection,
    scale="0.5c",
    cmap=True,
    outline=True,
)
# Add a colorbar
fig.colorbar(frame="x+lmoment magnitude")

fig.show()

Perfect, thanks very much for your time!