From 7ee5a14b52a4814ab86b0cfe793ea48c82427aac Mon Sep 17 00:00:00 2001 From: Dongdong Tian Date: Sun, 27 Nov 2022 13:12:54 +0800 Subject: [PATCH] Figure.meca: Fix beachball offsetting with dict/pandas inputs (#2202) Co-authored-by: Wei Ji <23487320+weiji14@users.noreply.github.com> --- pygmt/src/meca.py | 16 ++++++++++------ pygmt/tests/test_meca.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 6 deletions(-) diff --git a/pygmt/src/meca.py b/pygmt/src/meca.py index 86708730cde..da8ad18e9c0 100644 --- a/pygmt/src/meca.py +++ b/pygmt/src/meca.py @@ -189,11 +189,11 @@ def meca( Depth(s) of event location in kilometers. Must be the same length as the number of events. Will override the ``depth`` values in ``spec`` if ``spec`` is a dict or pd.DataFrame. - plot_longitude: int, float, list, or 1d numpy array + plot_longitude: int, float, str, list, or 1d numpy array Longitude(s) at which to place beachball. Must be the same length as the number of events. Will override the ``plot_longitude`` values in ``spec`` if ``spec`` is a dict or pd.DataFrame. - plot_latitude: int, float, list, or 1d numpy array + plot_latitude: int, float, str, list, or 1d numpy array Latitude(s) at which to place beachball. List must be the same length as the number of events. Will override the ``plot_latitude`` values in ``spec`` if ``spec`` is a dict or pd.DataFrame. @@ -272,10 +272,10 @@ def meca( spec["latitude"] = np.atleast_1d(latitude) if depth is not None: spec["depth"] = np.atleast_1d(depth) - if plot_longitude is not None: # must be in string type - spec["plot_longitude"] = np.atleast_1d(plot_longitude).astype(str) - if plot_latitude is not None: # must be in string type - spec["plot_latitude"] = np.atleast_1d(plot_latitude).astype(str) + if plot_longitude is not None: + spec["plot_longitude"] = np.atleast_1d(plot_longitude) + if plot_latitude is not None: + spec["plot_latitude"] = np.atleast_1d(plot_latitude) if event_name is not None: spec["event_name"] = np.atleast_1d(event_name).astype(str) @@ -293,9 +293,13 @@ def meca( newcols = ["longitude", "latitude", "depth"] + param_conventions[convention] if "plot_longitude" in spec.columns and "plot_latitude" in spec.columns: newcols += ["plot_longitude", "plot_latitude"] + spec[["plot_longitude", "plot_latitude"]] = spec[ + ["plot_longitude", "plot_latitude"] + ].astype(str) kwargs["A"] = True if "event_name" in spec.columns: newcols += ["event_name"] + spec["event_name"] = spec["event_name"].astype(str) # reorder columns in DataFrame spec = spec.reindex(newcols, axis=1) elif isinstance(spec, np.ndarray) and spec.ndim == 1: diff --git a/pygmt/tests/test_meca.py b/pygmt/tests/test_meca.py index ea7486079a2..16b9a6a4ef7 100644 --- a/pygmt/tests/test_meca.py +++ b/pygmt/tests/test_meca.py @@ -253,6 +253,34 @@ def test_meca_dict_offset(): return fig +@pytest.mark.mpl_image_compare(filename="test_meca_dict_offset.png") +def test_meca_dict_offset_in_dict(): + """ + Test offsetting beachballs for a dict input with offset parameters in the + dict. + + See https://github.com/GenericMappingTools/pygmt/issues/2016. + """ + fig = Figure() + focal_mechanism = dict( + strike=330, + dip=30, + rake=90, + magnitude=3, + plot_longitude=-124.5, + plot_latitude=47.5, + ) + fig.basemap(region=[-125, -122, 47, 49], projection="M6c", frame=True) + fig.meca( + spec=focal_mechanism, + scale="1c", + longitude=-124, + latitude=48, + depth=12.0, + ) + return fig + + @pytest.mark.mpl_image_compare def test_meca_dict_eventname(): """