Skip to content

beachball offsetting doesn't work for pandas/dict/ndarray input #2016

Closed

Description

@MsDannie76

I am trying to plot focal mechanisms on a map with an offset. I’ve tried to follow the tips given here:
[ PyGMT: How to offset focal mechanism beachballs?]
but still cannot get it to work, the two beachballs in the southeast are still plotted on top of each other, although there is no error message.
FM_reg1_ex

My file contains the columns
longitude latitude depth strike dip rake magnitude plot_longitude plot_latitude
and columns are separated by tabs:

|longitude|latitude|depth|strike|dip|rake|magnitude|plot_longitude|plot_latitude|
|1.4421|51.2819|15.5|47.28|32.05|112.09|4.5|1.4421|52|
|1.3884|51.3337|17|69.84|25.88|151.52|4.5|0.75|51.3337|
|-0.055|53.648|19.3|21.33|84.92|-19.37|4.1|-0.055|53.648|
|-1.314|54.594|4.6|102.1|84.1|-162|3.1|-1.314|54.594|
FM_ISC_exampleplot.txt

I reported that issue on the GMT community forum
[Pygmt psmeca beachball - no offset despite following tips from previous post]

Full code that generated the error

import pygmt
import pandas as pd

FM_ISCex=pd.read_csv("FM_ISC_exampleplot.txt",delimiter="\t")

fig = pygmt.Figure()
fig.coast(
region="-2/2/51/55",
projection="M15c",
land="lightgray",
water="white",
borders="1/0.5p",
shorelines="1/0.5p",
frame="ag",
)

fig.meca(
spec=FM_ISCex,
convention="aki",
scale="2c",
G="red",
offset=True
)

fig.show()

Full error message

No error message, but offset given as plot_longitude and plot_latitude is not used during plotting.

System information

Please paste the output of python -c "import pygmt; pygmt.show_versions()":

pygmt installed in Anaconda Navigator, seems to be version 0.3.1

Activity

  1. welcome commented on Jul 19, 2022

    @welcome

    👋 Thanks for opening your first issue here! Please make sure you filled out the template with as much detail as possible. You might also want to take a look at our contributing guidelines and code of conduct.

  2. seisman commented on Jul 19, 2022

    @seisman
    Member

    The meca() function is known to have issues/limitations in old PyGMT versions. We have fully rewritten the meca function after v0.7.0. Please try to install the PyGMT dev version using the following command:

    pip install --pre --extra-index-url https://test.pypi.org/simple/ pygmt
    

    After installing the PyGMT dev version, you'll see that it still doesn't work as expected, but at least setting spec="FM_ISC_exampleplot.txt" works.

  3. MsDannie76 commented on Jul 20, 2022

    @MsDannie76
    Author

    Hi,

    I upgraded to v0.7.0 . I am not sure that I understand you correctly. I don't mind reading in the file in separately, I only mind that I cannot offset the beachballs. If that also will not work in the dev-version, I'd rather stick to the normal version, or does it? (It does not seem to work in v0.7.0, either.)

  4. seisman commented on Jul 20, 2022

    @seisman
    Member

    The following script works for me with both PyGMT v0.7.0 and the dev version:

    import pygmt
    import pandas as pd
    
    fig = pygmt.Figure()
    fig.coast(
        region="-2/2/51/55",
        projection="M15c",
        land="lightgray",
        water="white",
        borders="1/0.5p",
        shorelines="1/0.5p",
        frame="ag",
    )
    
    fig.meca(
        spec="FM_ISC_exampleplot.txt", convention="aki", scale="2c", G="red", offset=True
    )
    fig.show()
    

    The output image is:

    focal

  5. MsDannie76 commented on Jul 20, 2022

    @MsDannie76
    Author

    OK, great, thanks! It now works for me in v0.7.0 as well as long as I directly read the file using meca and not go via pandas.

  6. changed the title [-]Pygmt psmeca beachball - no offset despite following tips from previous post[/-] [+]beachball offsetting doesn't work for pandas input[/+] on Jul 20, 2022
  7. yvonnefroehlich commented on Jul 20, 2022

    @yvonnefroehlich
    Member

    I think the same problem occurs when passing a dictionary (dict) to spec (at least for PyGMT v0.7.0):

    import pygmt
    
    #------------------------------------------------------------------------------
    # set up dictonary
    dict_meca = {
        "longitude": 1,
        "latitude": 52,
        "depth": 10,
        "strike": 100,
        "dip": 50,
        "rake": 20,
        "magnitude": 5,
        "plot_longitude": 1,
        "plot_latitude": 53,
        }
    
    #------------------------------------------------------------------------------
    # create figure object
    fig = pygmt.Figure()
    
    fig.coast(
        region="-2/2/51/55",
        projection="M15c",
        land="lightgray",
        water="white",
        borders="1/0.5p",
        shorelines="1/0.5p",
        frame="ag",
        )
    
    fig.meca(
        spec=dict_meca,
        convention="aki",
        scale="2c",
        G="red",
        offset=True,
        )
    
    fig.show()

    The beachball should be offset to latitude 53, but is plotted at latitude 52, which is the event latitude:

    meca_offset_dic

  8. changed the title [-]beachball offsetting doesn't work for pandas input[/-] [+]beachball offsetting doesn't work for pandas/dict input[/+] on Jul 20, 2022
  9. added this to the 0.8.0 milestone on Jul 20, 2022
  10. self-assigned this
    on Jul 20, 2022
  11. weiji14 commented on Nov 24, 2022

    @weiji14
    Member

    As a workaround for PyGMT v0.7.0, if you can set your plot_longitude and plot_latitude values to a str type (i.e. wrapping your numbers in quotes like '53'), then the beachball offset should work. E.g. using @yvonnefroehlich's code at #2016 (comment)

    dict_meca = {
        "longitude": 1,
        "latitude": 52,
        "depth": 10,
        "strike": 100,
        "dip": 50,
        "rake": 20,
        "magnitude": 5,
        "plot_longitude": "1",
        "plot_latitude": "53",
    }

    should give:

    beachball_at_53N

    Notice how the beachball is now at 53N instead of 52N. For those using pandas.DataFrame inputs, there should be a way to convert your plot_longitude and plot_latitude columns to str type too using astype. Something like df["plot_longitude"].astype(dtype=str").

    This will be fixed properly in #2202 (so that numeric int/float inputs will work) and should be available in the upcoming PyGMT v0.8.0. Thanks @seisman for identifying the issue!

  12. changed the title [-]beachball offsetting doesn't work for pandas/dict input[/-] [+]beachball offsetting doesn't work for pandas/dict/ndarray input[/+] on Nov 25, 2022
  13. yvonnefroehlich commented on Dec 4, 2022

    @yvonnefroehlich
    Member

    As a workaround for PyGMT v0.7.0, if you can set your plot_longitude and plot_latitude values to a str type (i.e. wrapping your numbers in quotes like '53'), then the beachball offset should work. E.g. using @yvonnefroehlich's code at #2016 (comment)

    For me stetting the arguments for plot_longitude and plot_latitude into quotation marks (i.e. string input) does not work with PyGMT v0.7.0 and GMT 6.4.0:

    Example script

    import pygmt
    
    # use dictonary to provided focal mechanism data (aki convention)
    dict_meca = {
        "longitude": 0,
        "latitude": 0,
        "depth": 12,
        "strike": 330,
        "dip": 30,
        "rake": 90,
        "magnitude": 5,
        # "plot_longitude": 2,
        # "plot_latitude": 2,
        "plot_longitude": "2",  # trick use string input
        "plot_latitude": "2",
    }
    
    fig = pygmt.Figure()
    
    fig.basemap(
        region=[-5, 5, -5, 5],
        projection="X10c",
        frame="afg",
    )
    
    fig.meca(
        spec=dict_meca,
        convention="aki",
        scale="1c",
        offset=True,
    )
    
    fig.show()

    Error message

    Traceback (most recent call last):
    
      File "C:\ProgramData\Anaconda3\envs\pygmt_env_070_640\lib\site-packages\spyder_kernels\py3compat.py", line 356, in compat_exec
        exec(code, globals, locals)
    
      File "c:\users\admin\c2\eigenedokumente\studium\promotion\e_gmt\00_testing\issuse_meca_offset\meca_offset_line.py", line 62, in <module>
        fig.meca(
    
      File "C:\ProgramData\Anaconda3\envs\pygmt_env_070_640\lib\site-packages\pygmt\helpers\decorators.py", line 585, in new_module
        return module_func(*args, **kwargs)
    
      File "C:\ProgramData\Anaconda3\envs\pygmt_env_070_640\lib\site-packages\pygmt\helpers\decorators.py", line 725, in new_module
        return module_func(*args, **kwargs)
    
      File "C:\ProgramData\Anaconda3\envs\pygmt_env_070_640\lib\site-packages\pygmt\src\meca.py", line 466, in meca
        with file_context as fname:
    
      File "C:\ProgramData\Anaconda3\envs\pygmt_env_070_640\lib\contextlib.py", line 119, in __enter__
        return next(self.gen)
    
      File "C:\ProgramData\Anaconda3\envs\pygmt_env_070_640\lib\site-packages\pygmt\clib\session.py", line 1259, in virtualfile_from_matrix
        self.put_matrix(dataset, matrix)
    
      File "C:\ProgramData\Anaconda3\envs\pygmt_env_070_640\lib\site-packages\pygmt\clib\session.py", line 901, in put_matrix
        raise GMTCLibError(f"Failed to put matrix of type {matrix.dtype}.")
    
    GMTCLibError: Failed to put matrix of type <U11.
    

    Output of pygmt.show_versions()

    PyGMT information:
      version: v0.7.0
    System information:
      python: 3.9.13 | packaged by conda-forge | (main, May 27 2022, 16:50:36) [MSC v.1929 64 bit (AMD64)]
      executable: C:\ProgramData\Anaconda3\envs\pygmt_env_070_640\python.exe
      machine: Windows-10-10.0.19045-SP0
    Dependency information:
      numpy: 1.23.1
      pandas: 1.4.3
      xarray: 2022.6.0
      netCDF4: 1.6.0
      packaging: 21.3
      geopandas: 0.11.1
      ghostscript: 9.54.0
      gmt: 6.4.0
    GMT library information:
      binary dir: C:/ProgramData/Anaconda3/envs/pygmt_env_070_640
      cores: 4
      grid layout: rows
      library path: C:/ProgramData/Anaconda3/envs/pygmt_env_070_640/Library/bin/gmt.dll
      padding: 2
      plugin dir: C:/ProgramData/Anaconda3/envs/pygmt_env_070_640/Library/bin/gmt_plugins
      share dir: C:/Program Files (x86)/gmt6/share
      version: 6.4.0
    
  14. yvonnefroehlich commented on Dec 4, 2022

    @yvonnefroehlich
    Member

    An other aspect is, that the line and the small circle are not plotted or modified via the offset parameter (see
    https://www.pygmt.org/dev/api/generated/pygmt.Figure.meca.html#pygmt.Figure.meca) when passing a dictionary to spec (see case (II)). It works when reading the focal mechanism data from a text file (see case (I)). In both cases a PyGMT dev version (after PR #2202 was megerd) was used.

    Example script

    import pygmt
    
    #------------------------------------------------------------------------------
    # (I) read focal mechanism data from input file (aki convention)
    fig = pygmt.Figure()
    
    fig.basemap(
        region=[-5, 5, -5, 5],
        projection="X10c",
        frame="afg",
    )
    
    fig.meca(
        spec="gmt_meca_doc.txt",
        scale="1c",
        offset="+p1p,green+s0.5c",  # line thickness and color, size of circle
        convention="aki",
    )
    
    fig.show()
    # fig.savefig(fname="meca_offset_line_file.png")
    
    # ------------------------------------------------------------------------------
    # (II) use dictionary to provided focal mechanism data (aki convention)
    dict_meca = {
        "longitude": 0,
        "latitude": 0,
        "depth": 12,
        "strike": 330,
        "dip": 30,
        "rake": 90,
        "magnitude": 5,
        "plot_longitude": 2,
        "plot_latitude": 2,
    }
    
    fig = pygmt.Figure()
    
    fig.basemap(
        region=[-5, 5, -5, 5],
        projection="X10c",
        frame="afg",
    )
    
    fig.meca(
        spec=dict_meca,
        convention="aki",
        scale="1c",
        offset="+p1p,green+s0.5c",  # line thickness and color, size of circle
    )
    
    fig.show()
    # fig.savefig(fname="meca_offset_line_dict.png")

    Output figure for (I) reading a txt file (expectation)
    meca_offset_line_file

    Output figure for (II) using a dictionary
    meca_offset_line_dict

    Output of pygmt.show_versions()

    PyGMT information:
      version: v0.7.1.dev170
    System information:
      python: 3.9.15 | packaged by conda-forge | (main, Nov 22 2022, 08:39:05) [MSC v.1929 64 bit (AMD64)]
      executable: C:\ProgramData\Anaconda3\envs\pygmt_env_080_640_dev02\python.exe
      machine: Windows-10-10.0.19045-SP0
    Dependency information:
      numpy: 1.23.5
      pandas: 1.5.2
      xarray: 2022.12.0
      netCDF4: 1.6.2
      packaging: 21.3
      geopandas: None
      ghostscript: 9.54.0
    GMT library information:
      binary version: 6.4.0
      cores: 4
      grid layout: rows
      library path: C:/ProgramData/Anaconda3/envs/pygmt_env_080_640_dev02/Library/bin/gmt.dll
      padding: 2
      plugin dir: C:/ProgramData/Anaconda3/envs/pygmt_env_080_640_dev02/Library/bin/gmt_plugins
      share dir: C:/Program Files (x86)/gmt6/share
      version: 6.4.0
    
  15. 3 remaining items

  16. seisman commented on Dec 20, 2022

    @seisman
    Member

    Can we close this issue? It should be now (hopefully) fixed by #2202 and Figure.meca: Fix line and circle of offset parameter for dict/pandas input #2226.

    Beachball offsetting may still fail for ndarray input. Need some time to test.

  17. yvonnefroehlich commented on Dec 20, 2022

    @yvonnefroehlich
    Member

    Can we close this issue? It should be now (hopefully) fixed by #2202 and Figure.meca: Fix line and circle of offset parameter for dict/pandas input #2226.

    Beachball offsetting may still fail for ndarray input. Need some time to test.

    Thanks! I see the updated issue title. Hm, then bump this back to v0.9.0 🙂?

  18. seisman commented on Dec 21, 2022

    @seisman
    Member

    I'll see if I can finish it before v0.8.0.

  19. modified the milestones: 0.8.0, 0.9.0 on Dec 24, 2022
  20. seisman commented on Dec 24, 2022

    @seisman
    Member

    I'm bumping this issue to v0.9.0 because beachball offsetting for ndarray input is more tricky than I initially thought so I can't finish it soon.

  21. weiji14 commented on Mar 6, 2023

    @weiji14
    Member

    I'm bumping this issue to v0.9.0 because beachball offsetting for ndarray input is more tricky than I initially thought so I can't finish it soon.

    Do you have time to work on this before end of March 2023? Or should we bump this to PyGMT v0.10.0?

  22. seisman commented on Mar 6, 2023

    @seisman
    Member

    I'll give it another try in the following week.

  23. modified the milestones: 0.9.0, 0.10.0 on Mar 15, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions