Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an advanced tutorial for plotting focal mechanisms (beachballs) #2550

Merged
merged 154 commits into from
Mar 24, 2025
Merged
Changes from all commits
Commits
Show all changes
154 commits
Select commit Hold shift + click to select a range
9a031b2
Add basic structur and code examples for meca tutorial
yvonnefroehlich May 29, 2023
24802bb
Fix typos
yvonnefroehlich May 29, 2023
686bf92
[format-command] fixes
actions-bot May 29, 2023
744cf3f
Use 'nodal', Adjust front size of 'event_name' label
yvonnefroehlich May 30, 2023
f3f0bd3
Remove color-coding from section 'Add label'
yvonnefroehlich May 30, 2023
9d19715
Add section 'Plot several beachballs'
yvonnefroehlich May 30, 2023
ba9debf
Expand convention list, Adjust the other lists in the introduction part
yvonnefroehlich May 30, 2023
5e12f74
Fix line length
yvonnefroehlich May 30, 2023
4a8a24e
Adjust code and comments
yvonnefroehlich May 30, 2023
e2d705d
Adjust thumbnail figure
yvonnefroehlich May 30, 2023
725f54d
Fix code comment
yvonnefroehlich May 30, 2023
ec06281
Adjust stuff regarding 'input data'
yvonnefroehlich May 31, 2023
f6b77d1
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Jun 7, 2023
e97f1b4
Use aliases for 'L', 'T', and 'Fr'
yvonnefroehlich Jun 10, 2023
2c31093
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Jun 12, 2023
c0662fb
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Jul 3, 2023
05e323d
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Sep 2, 2023
4a390fc
Add remark regarding GMT issue #7777 and PR #7778
yvonnefroehlich Sep 3, 2023
96ee768
Add empty line after heading in tutorial 'focal_mechanisms.py'
yvonnefroehlich Sep 4, 2023
16fae40
Update code separate in tutorial 'focal_mechanisms.py'
yvonnefroehlich Sep 4, 2023
af105a3
Use two empty lines befor sub-sections
yvonnefroehlich Sep 4, 2023
a457331
Use empty line after sub-section
yvonnefroehlich Sep 4, 2023
2293b38
Use correct order of regarding sphinx thumbnail
yvonnefroehlich Sep 7, 2023
735b314
Fix typos
yvonnefroehlich Sep 7, 2023
a787467
Move 'sphinx_gallery_thumbnail_number' comand line to end of script
yvonnefroehlich Sep 9, 2023
f58843b
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Sep 10, 2023
8007aed
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Sep 11, 2023
cc6357e
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Sep 15, 2023
c404293
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Sep 26, 2023
a7c0c9d
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Oct 5, 2023
3319916
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Oct 15, 2023
fbf37f9
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Oct 18, 2023
3cf475e
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Nov 2, 2023
69ce531
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Nov 21, 2023
eff5567
Shorten code and docs
yvonnefroehlich Nov 23, 2023
39f055e
Change study area
yvonnefroehlich Nov 23, 2023
b41fde2
Replace tab by four spaces
yvonnefroehlich Nov 23, 2023
0f687c9
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Nov 23, 2023
1d9f05a
Consider maximum line length
Nov 23, 2023
be8be06
Follow ruff's C4 rules
yvonnefroehlich Dec 16, 2023
4607189
Adjust colors to shorten script length
yvonnefroehlich Dec 16, 2023
e4bf3a7
[format-command] fixes
actions-bot Dec 16, 2023
3cc11a1
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Dec 16, 2023
5166a15
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Jan 2, 2024
da369b6
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Jan 5, 2024
8c8a442
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Mar 14, 2024
118ed00
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Mar 30, 2024
2ce90e8
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Apr 5, 2024
6d870fc
Improve documetation
yvonnefroehlich Apr 11, 2024
6eac949
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Apr 11, 2024
649bf83
Fix length of underline
yvonnefroehlich Apr 18, 2024
eec5e37
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich May 2, 2024
828ef97
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich May 21, 2024
8ab43e2
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Jun 20, 2024
482452f
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Jun 21, 2024
3c6a225
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Aug 12, 2024
28044fc
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Sep 1, 2024
792be20
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Sep 8, 2024
d35395e
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Sep 30, 2024
2f04a60
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Oct 12, 2024
7f8daa3
General update of code
yvonnefroehlich Oct 13, 2024
d018e49
Remove execution permission
yvonnefroehlich Oct 13, 2024
b033019
Adjust figure size
yvonnefroehlich Oct 13, 2024
ee0c18f
Adjust figure size
yvonnefroehlich Oct 13, 2024
0692453
Adjust figure size
yvonnefroehlich Oct 13, 2024
de50cd5
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Oct 13, 2024
515c87b
Fix highlighting
yvonnefroehlich Oct 13, 2024
e6e57f7
Fix highlighting
yvonnefroehlich Oct 13, 2024
d4a3d56
Use different input formats and events
yvonnefroehlich Oct 14, 2024
257077a
Improve formulation of content list and headings
yvonnefroehlich Oct 14, 2024
2c32da7
Invert colormap
yvonnefroehlich Oct 14, 2024
7b47d2d
Use a continous colormap
yvonnefroehlich Oct 14, 2024
d898e0b
Update earthqauke data
yvonnefroehlich Oct 14, 2024
72e5cc6
Update comment | Fix typo
yvonnefroehlich Oct 14, 2024
96f3240
Add comments
yvonnefroehlich Oct 14, 2024
34fbbd5
Add comments
yvonnefroehlich Oct 14, 2024
2347ac7
Update introduction part
yvonnefroehlich Oct 14, 2024
6228447
Add links to pattern resources
yvonnefroehlich Oct 14, 2024
e3e0696
Update comments
yvonnefroehlich Oct 14, 2024
4a675b1
Update comments
yvonnefroehlich Oct 14, 2024
48bcdf8
Update comments
yvonnefroehlich Oct 14, 2024
7718e7b
Remove exectuion permission
yvonnefroehlich Oct 14, 2024
998e42d
Update introduction part
yvonnefroehlich Oct 14, 2024
13e600b
Expand comments
yvonnefroehlich Oct 14, 2024
f146079
Add example for 'component' parameter
yvonnefroehlich Oct 14, 2024
2260e6c
Update headings
yvonnefroehlich Oct 14, 2024
645f5f1
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Oct 15, 2024
65b09b6
Convert from list to text
yvonnefroehlich Oct 15, 2024
649def2
Expand docs
yvonnefroehlich Oct 15, 2024
091c898
Format introduction part
yvonnefroehlich Oct 15, 2024
f759a40
Add blank line
yvonnefroehlich Oct 15, 2024
ae2fb87
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Oct 16, 2024
02de7ff
Add section for plotting P and T axes
yvonnefroehlich Oct 17, 2024
e7ec741
Remove execution permission
yvonnefroehlich Oct 17, 2024
d49ccbb
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Nov 6, 2024
f304b13
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Nov 17, 2024
68b5aa7
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Jan 2, 2025
5dddbc5
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Feb 3, 2025
4622f1e
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Feb 13, 2025
b65f5cf
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Feb 15, 2025
3d235dd
Rewrap line length
yvonnefroehlich Feb 16, 2025
479b1ad
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Feb 19, 2025
5dbea74
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Feb 27, 2025
e5151ff
Remove code examples for T and P axes
yvonnefroehlich Mar 7, 2025
bcc8a5d
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Mar 7, 2025
f1b3c14
Fix highlighting, formulations, interpuncation
yvonnefroehlich Mar 10, 2025
34c392c
Define region directly
yvonnefroehlich Mar 10, 2025
5815c98
Remove mixed up variable name
yvonnefroehlich Mar 10, 2025
8716f0a
Fix highlighting
yvonnefroehlich Mar 10, 2025
f34979c
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Mar 10, 2025
96bbe1b
Add depth
yvonnefroehlich Mar 10, 2025
5bc0025
Fix comment
yvonnefroehlich Mar 10, 2025
e7ad5fe
Fix typo
yvonnefroehlich Mar 10, 2025
000d38b
Fix thumbnail image
yvonnefroehlich Mar 11, 2025
e699445
Fix highlighting
yvonnefroehlich Mar 11, 2025
5f6dc3b
Make formulation sound nicer
yvonnefroehlich Mar 11, 2025
a02a725
Make formulation seismically for descriptive
yvonnefroehlich Mar 11, 2025
4375ae9
Make formulation more related to the user
yvonnefroehlich Mar 11, 2025
c9d07ba
Fix code to comment
yvonnefroehlich Mar 11, 2025
f6afebf
Remove training white spaces
yvonnefroehlich Mar 11, 2025
4055d02
Fix code to comment
yvonnefroehlich Mar 11, 2025
57121bf
Move section for *fill up
yvonnefroehlich Mar 11, 2025
350d01d
Explain scale parameter regarding size
yvonnefroehlich Mar 11, 2025
abb7ae7
Fix typo
yvonnefroehlich Mar 11, 2025
40a330d
Combine setting up dictionary and converting to dataframe
yvonnefroehlich Mar 12, 2025
15cc0e1
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Mar 12, 2025
b0c7752
Remove datatype from variable name
yvonnefroehlich Mar 12, 2025
5dfdc96
Remove offset parameter for dict input
yvonnefroehlich Mar 12, 2025
8d19aad
Improve explanaition of offset parameter
yvonnefroehlich Mar 12, 2025
5ed896d
Use for loop for component parameter
yvonnefroehlich Mar 12, 2025
379cdb1
Add explanation for muliple beachballs
yvonnefroehlich Mar 12, 2025
4214b71
Remove unneeded pen attribute
yvonnefroehlich Mar 13, 2025
20a70f0
Use math mode
yvonnefroehlich Mar 13, 2025
7031b26
Use zip
yvonnefroehlich Mar 13, 2025
a586f11
Fix code style
yvonnefroehlich Mar 13, 2025
eb158bb
Adjust spacing
yvonnefroehlich Mar 13, 2025
8f6cab6
Fix math mode
yvonnefroehlich Mar 14, 2025
73f24b4
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Mar 14, 2025
9925eab
Fix math mode
yvonnefroehlich Mar 15, 2025
46dc736
Remove overview list
yvonnefroehlich Mar 15, 2025
fb70e78
Remove trailing white space
yvonnefroehlich Mar 15, 2025
6709e51
Fix typo
yvonnefroehlich Mar 15, 2025
ddf6211
Use line length
yvonnefroehlich Mar 15, 2025
6574f7e
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Mar 18, 2025
e37421a
Use for loop and dicts
yvonnefroehlich Mar 18, 2025
ac88165
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Mar 20, 2025
14b31b4
Fix code style
yvonnefroehlich Mar 20, 2025
4a87d23
Improve docs
yvonnefroehlich Mar 22, 2025
6f449fe
Improve docs
yvonnefroehlich Mar 22, 2025
93712b2
Use equal space between beachballs
yvonnefroehlich Mar 22, 2025
8933633
Merge branch 'main' into add-tutorial-meca
yvonnefroehlich Mar 22, 2025
4489590
Fix typos
yvonnefroehlich Mar 23, 2025
0577297
Merge branch 'main' into add-tutorial-meca
michaelgrund Mar 24, 2025
7e52907
Fix a lot of typos
yvonnefroehlich Mar 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
327 changes: 327 additions & 0 deletions examples/tutorials/advanced/focal_mechanisms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,327 @@
"""
Plotting focal mechanisms
=========================

Focal mechanisms can be plotted as beachballs with the :meth:`pygmt.Figure.meca` method.

The focal mechanism data or parameters can be provided as various input types: ASCII
file, :class:`numpy.array`, dictionary, or :class:`pandas.Dataframe`. Different
conventions to define the focal mechanism are supported: Aki and Richards (``"aki"``),
global CMT (``"gcmt"``), moment tensor (``"mt"``), partial focal mechanism
(``"partial"``), and, principal axis (``"principal_axis"``). Please refer to the table
in the documentation of :meth:`pygmt.Figure.meca` regarding how to set up the input data
in respect to the chosen input type and convention (i.e., the expected column order,
keys, or column names). In this tutorial we focus on how to adjust the display of the
beachballs.
"""

# %%
import pandas as pd
import pygmt

# Set up arguments for basemap
region = [-5, 5, -5, 5]
projection = "X10c/4c"
frame = ["af", "+ggray90"]


# %%
# Setting up the focal mechanism data
# -----------------------------------
#
# We store focal mechanism parameters for two single events in dictionaries using the
# moment tensor and Aki and Richards conventions:

# moment tensor convention
mt_single = {
"mrr": 4.71,
"mtt": 0.0381,
"mff": -4.74,
"mrt": 0.399,
"mrf": -0.805,
"mtf": -1.23,
"exponent": 24,
}
# Aki and Richards convention
aki_single = {"strike": 318, "dip": 89, "rake": -179, "magnitude": 7.75}


# %%
# Plotting a single beachball
# ---------------------------
#
# Required parameters are ``spec`` and ``scale`` as well as ``longitude``, ``latitude``
# (event location), and depth (if these values are not included in the argument passed
# to ``spec``). Additionally, the ``convention`` parameter is required if ``spec`` is
# an 1-D or 2-D numpy array; for the input types dictionary and ``pandas.Dataframe``,
# the focal mechanism convention is automatically determined from dictionary keys or
# :class:`pandas.DataFrame` column names. The ``scale`` parameter controls the radius
# of the beachball. By default, the value defines the size for a magnitude of 5 (i.e.,
# a scalar seismic moment of :math:`M_0 = 4.0 \times 10^{23}` dyn cm) and the beachball
# size is proportional to the magnitude. Append ``"+l"`` to force the radius to be
# proportional to the seismic moment.

fig = pygmt.Figure()
fig.basemap(region=region, projection=projection, frame=frame)

fig.meca(spec=mt_single, scale="1c", longitude=0, latitude=0, depth=0)

fig.show()


# %%
# Plotting the components of a seismic moment tensor
# --------------------------------------------------
#
# A moment tensor can be decomposed into isotropic and deviatoric parts. The deviatoric
# part can be further decomposed into multiple parts (e.g., a double couple (DC) and a
# compensated linear vector dipole (CLVD)). Use the ``component`` parameter to specify
# the component you want to plot.

fig = pygmt.Figure()
fig.basemap(region=region, projection=projection, frame=frame)

for component, longitude in zip(["full", "dc", "deviatoric"], [-2, 0, 2], strict=True):
fig.meca(
spec=mt_single,
scale="1c",
longitude=longitude,
latitude=0,
depth=0,
component=component,
)

fig.show()


# %%
# Filling the quadrants
# ---------------------
#
# Use the parameters ``compressionfill`` and ``extensionfill`` to fill the quadrants
# with different colors or patterns. Regarding patterns see the gallery example
# :doc:`Bit and hachure patterns </gallery/symbols/patterns>` and the Technical
# Reference :doc:`Bit and hachure patterns </techref/patterns>`.

fig = pygmt.Figure()
fig.basemap(region=region, projection=projection, frame=frame)

fig.meca(
spec=mt_single,
scale="1c",
longitude=-2,
latitude=0,
depth=0,
compressionfill="darkorange",
extensionfill="cornsilk",
)

fig.meca(
spec=mt_single,
scale="1c",
longitude=2,
latitude=0,
depth=0,
compressionfill="p8",
extensionfill="p31",
outline=True,
)

fig.show()


# %%
# Adjusting the outlines
# ----------------------
#
# Use the parameters ``pen`` and ``outline`` for adjusting the circumference of the
# beachball or all lines (i.e, circumference and both nodal planes).

fig = pygmt.Figure()
fig.basemap(region=region, projection=projection, frame=frame)

fig.meca(
spec=aki_single,
scale="1c",
longitude=-2,
latitude=0,
depth=0,
# Use a 1-point thick, darkorange and solid line
pen="1p,darkorange",
)

fig.meca(
spec=aki_single,
scale="1c",
longitude=2,
latitude=0,
depth=0,
outline="1p,darkorange",
)

fig.show()


# %%
# Highlighting the nodal planes
# -----------------------------
#
# Use the parameter ``nodal`` to highlight specific nodal planes. ``"0"`` refers to
# both, ``"1"`` to the first, and ``"2"`` to the second nodal plane(s). Only the
# circumference and the specified nodal plane(s) are plotted, i.e. the quadrants
# remain unfilled (transparent). We can make use of the stacking concept of (Py)GMT,
# and use ``nodal`` in combination with the ``outline``, ``compressionfill`` /
# ``extensionfill`` and ``pen`` parameters.

fig = pygmt.Figure()
fig.basemap(region=region, projection=projection, frame=frame)

fig.meca(
spec=aki_single,
scale="1c",
longitude=-2,
latitude=0,
depth=0,
nodal="0/1p,black",
)

# Plot the same beachball three times with different settings:
# (i) Fill the compressive quadrants
# (ii) Plot the first nodal plane and the circumference in darkorange
# (iii) Plot the circumfence in black on top; use "-" to not fill the quadrants
for kwargs in [
{"compressionfill": "lightorange"},
{"nodal": "1/1p,darkorange"},
{"compressionfill": "-", "extensionfill": "-", "pen": "1p,gray30"},
]:
fig.meca(
spec=aki_single,
scale="1c",
longitude=0,
latitude=0,
depth=0,
**kwargs,
)
fig.show()


# %%
# Adding offset from event location
# ---------------------------------
#
# Specify the optional parameters ``plot_longitude`` and ``plot_latitude``. If ``spec``
# is an ASCII file with columns for ``plot_longitude`` and ``plot_latitude``, the
# ``offset`` parameter has to be set to ``True``. Besides just drawing a line between
# the beachball and the event location, a small circle can be plotted at the event
# location by appending **+s** and the descired circle diameter. The connecting line as
# well as the outline of the circle are plotted with the setting of pen, or can be
# adjusted separately. The fill of the small circle corresponds to the fill of the
# compressive quadrantes.

fig = pygmt.Figure()
fig.basemap(region=region, projection=projection, frame=frame)

fig.meca(
spec=aki_single,
scale="1c",
longitude=-1,
latitude=0,
depth=0,
plot_longitude=-3,
plot_latitude=2,
)

fig.meca(
spec=aki_single,
scale="1c",
longitude=3,
latitude=0,
depth=0,
plot_longitude=1,
plot_latitude=2,
offset="+p1p,darkorange+s0.25c",
compressionfill="lightorange",
)

fig.show()


# %%
# Plotting multiple beachballs
# ----------------------------
#
# Now we want to plot multiple beachballs with one call of :meth:`pygmt.Figure.meca`. We
# use data of four earthquakes taken from USGS. For each focal mechanism parameter a
# list with a length corresponding to the number of events has to be given.

# Set up a pandas.DataFrame with multiple focal mechanism parameters.
aki_multiple = pd.DataFrame(
{
"strike": [255, 173, 295, 318],
"dip": [70, 68, 79, 89],
"rake": [20, 83, -177, -179],
"magnitude": [7.0, 5.8, 6.0, 7.8],
"longitude": [-72.53, -79.61, 69.46, 37.01],
"latitude": [18.44, 0.90, 33.02, 37.23],
"depth": [13, 19, 4, 10],
"plot_longitude": [-70, -110, 100, 0],
"plot_latitude": [40, 10, 50, 55],
"event_name": [
"Haiti - 2010/01/12",
"Esmeraldas - 2022/03/27",
"Afghanistan - 2022/06/21",
"Syria/Turkey - 2023/02/06",
],
}
)


# %%
# Adding a label
# --------------
#
# Use the optional parameter ``event_name`` to add a label near the beachball, e.g.,
# event name or event date and time. Change the font of the label text by appending
# **+f** and the desired font (size,name,color) to the argument passed to the ``scale``
# parameter. Additionally, the location of the label relative to the beachball [Default
# is ``"TC"``, i.e., Top Center] can be changed by appending **+j** and an offset can
# be applied by appending **+o** with values for *dx*\ /*dy*. Add a colored [Default is
# white] box behind the label via the label ``labelbox``. Force a fixed size of the
# beachball by appending **+m** to the argument passed to the ``scale`` parameter.

fig = pygmt.Figure()
fig.coast(region="d", projection="N10c", land="lightgray", frame=True)

fig.meca(spec=aki_multiple, scale="0.4c+m+f5p", labelbox="white@30", offset="+s0.1c")

fig.show()


# %%
# Using size-coding and color-coding
# ----------------------------------
#
# The beachball can be sized and colored by the quantities given as ``magnitude`` and
# ``depth``, e.g., by moment magnitude or hypocentral depth, respectively. Use the
# parameter ``cmap`` to pass the descired colormap. Now, the fills of the small circles
# indicating the event locations are given by the colormap.

fig = pygmt.Figure()
fig.coast(region="d", projection="N10c", land="lightgray", frame=True)

# Set up colormap and colorbar for hypocentral depth
pygmt.makecpt(cmap="lajolla", series=[0, 20])
fig.colorbar(frame=["x+lhypocentral depth", "y+lkm"])

fig.meca(
spec=aki_multiple,
scale="0.4c+f5p",
offset="0.2p,gray30+s0.1c",
labelbox="white@30",
cmap=True,
outline="0.2p,gray30",
)

fig.show()

# sphinx_gallery_thumbnail_number = 8