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

WIP: Add tutorial showing how to plot focal mechanisms (beachballs) #2550

Draft
wants to merge 98 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
Show all changes
98 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
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
370 changes: 370 additions & 0 deletions examples/tutorials/advanced/focal_mechanisms.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,370 @@
"""
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 different input
types: external file, 1-D or 2-D ``numpy.array``, dictionary, ``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"``), principal axis (``"principal_axis"``). Please
refer to 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).

This tutorial focus on how to adjust the display of the beachballs:

- Filling the quadrants
- Plotting the P and T axes
- Plotting the components of a seismic moment tensor
- Adjusting the outlines
- Highlighting the nodal planes
- Adding offset from the event location
- Adding a label
- Using size-coding and color-coding
"""

# %%
import pandas as pd
import pygmt

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


# %%
# Set up the focal mechanism data
# -------------------------------
#
# Store focal mechanism parameters for one event in a dictionary following the

# moment tensor convention
mt_dict_single = mt_virginia = {
"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_dict_single = {"strike": 318, "dip": 89, "rake": -179, "magnitude": 7.75}


# %%
# Plotting a single beachball
# ---------------------------
#
# Required parameters are ``spec``, ``scale``, ``longitude`` and ``latitude``
# (event location) as well as ``convention``. For the input types dictionary and
# ``pandas.Dataframe``, ``convention`` is not required.

fig = pygmt.Figure()
fig.basemap(region=[-size, size] * 2, projection=projection, frame=frame)

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

fig.show()


# %%
# Filling the quadrants
# ---------------------
#
# Use the parameters ``compressionfill`` and ``extensionfill`` to fill the
# quadrants with different colors or patterns. Regarding pattern 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=[-size, size] * 2, projection=projection, frame=frame)

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

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

fig.show()


# %%
# Plotting the P and T axes
# -------------------------
#
# Wait for PR #3526

fig = pygmt.Figure()
fig.basemap(region=[-size, size] * 2, projection=projection, frame=frame)

fig.meca(
spec=mt_dict_single,
scale="1c",
longitude=-2,
latitude=0,
Fa=True,
)

fig.meca(
spec=mt_dict_single,
scale="1c",
longitude=2,
latitude=0,
Fa="0.2c/cd", # Compute and plot P and T axes with symbols, Adjust size and symbols
Fe="darkorange", # Adjust fill of T axis symbol
Fg="gray30", # Adjust fill of P axis symbol
Ft="0.8p,cornsilk", # Adjust outline of T axis symbol
Fp="0.8p,gray60", # Adjust outline of P axis symbol
)

fig.show()


# %%
# Plotting the components of a seismic moment tensor
# --------------------------------------------------
#
# Use the ``component`` parameter to plot the components of a seismic moment tensor.

fig = pygmt.Figure()
fig.basemap(region=[-size, size] * 2, projection=projection, frame=frame)

fig.meca(
spec=mt_dict_single,
scale="1c",
longitude=-3,
latitude=0,
component="full", # full seismic moment tensor
)
fig.meca(
spec=mt_dict_single,
scale="1c",
longitude=0,
latitude=0,
component="dc", # closest double couple
)
fig.meca(
spec=mt_dict_single,
scale="1c",
longitude=2,
latitude=0,
component="deviatoric", # deviatoric part
)

fig.show()


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

fig = pygmt.Figure()
fig.basemap(region=[-size, size] * 2, projection=projection, frame=frame)

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

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

fig.show()


# %%
# Highlighting the nodal planes
# -----------------------------
#
# Use the parameter ``nodal``, whereby ``"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). If needed, make usage of the stacking concept of (Py)GMT and use
# ``nodal`` with the ``outline`` or / and ``pen`` parameters in combination.

fig = pygmt.Figure()
fig.basemap(region=[-size, size] * 2, projection=projection, frame=frame)

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

fig.meca(
spec=aki_dict_single,
scale="1c",
longitude=2,
latitude=0,
compressionfill="lightorange",
outline="0.5p,black,solid",
)
fig.meca(
spec=aki_dict_single,
scale="1c",
longitude=2,
latitude=0,
nodal="1/1p,darkorange,solid",
)
fig.meca(
spec=aki_dict_single,
scale="1c",
longitude=2,
latitude=0,
compressionfill="white@100",
extensionfill="white@100",
pen="1p,gray30,solid",
)
fig.show()


# %%
# Adding offset from event location
# ---------------------------------
#
# Specify the optional parameters ``plot_longitude`` and ``plot_latitude``.
# Additionally the parameter ``offset`` has to be set. 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=[-size, size] * 2, projection=projection, frame=frame)

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

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

fig.show()


# %%
# Plotting multiple beachballs
# ----------------------------
#
# Data of four earthquakes taken from USGS.
# Provide lists.

# Set up a dictionary
aki_dict_multiple = {
"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",
],
}
# Convert to a pandas.DataFrame
aki_df_multiple = pd.DataFrame(aki_dict_multiple)


# %%
# 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 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_df_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_df_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 = 9