Giter Site home page Giter Site logo

genericmappingtools / pygmt Goto Github PK

View Code? Open in Web Editor NEW
743.0 28.0 214.0 154.61 MB

A Python interface for the Generic Mapping Tools.

Home Page: https://www.pygmt.org

License: BSD 3-Clause "New" or "Revised" License

Makefile 0.27% Python 99.73%
python geoscience earth-science geophysics maps seismology hacktoberfest

pygmt's Introduction

PyGMT

A Python interface for the Generic Mapping Tools

Documentation (development version) | Contact | TryOnline

Latest version on PyPI Latest version on conda-forge GitHub Actions Tests status GitHub Actions GMT Dev Tests status Ruff Test coverage status CodSpeed Performance Benchmarks Compatible Python versions. Discourse forum Digital Object Identifier for the Zenodo archive PyOpenSci GitHub license Contributor Code of Conduct

Why PyGMT?

A beautiful map is worth a thousand words. To truly understand how powerful PyGMT is, play with it online on Binder! For a quicker introduction, check out our 3 minute overview!

Afterwards, feel free to look at our Tutorials, visit the Gallery, and check out some external PyGMT examples!

Quick Introduction to PyGMT YouTube Video

About

PyGMT is a library for processing geospatial and geophysical data and making publication-quality maps and figures. It provides a Pythonic interface for the Generic Mapping Tools (GMT), a command-line program widely used across the Earth, Ocean, and Planetary sciences and beyond.

Project goals

  • Make GMT more accessible to new users.
  • Build a Pythonic API for GMT.
  • Interface with the GMT C API directly using ctypes (no system calls).
  • Support for rich display in the Jupyter notebook.
  • Integration with the PyData ecosystem: numpy.ndarray or pandas.DataFrame for data tables, xarray.DataArray for grids, and geopandas.GeoDataFrame for geographical data.

Quickstart

Installation

Simple installation using mamba:

mamba install --channel conda-forge pygmt

If you use conda:

conda install --channel conda-forge pygmt

For other ways to install pygmt, see the full installation instructions.

Getting started

As a starting point, you can open a Python interpreter or a Jupyter notebook, and try the following example:

import pygmt
fig = pygmt.Figure()
fig.coast(projection="N15c", region="g", frame=True, land="tan", water="lightblue")
fig.text(position="MC", text="PyGMT", font="80p,Helvetica-Bold,red@75")
fig.show()

You should see a global map with land and water masses colored in tan and lightblue, respectively. On top, there should be the semi-transparent text "PyGMT". For more examples, please have a look at the Gallery and Tutorials.

Contacting us

Contributing

Code of conduct

Please note that this project is released with a Contributor Code of Conduct. By participating in this project you agree to abide by its terms.

Contributing guidelines

Please read our Contributing Guide to see how you can help and give feedback.

Imposter syndrome disclaimer

We want your help. No, really.

There may be a little voice inside your head that is telling you that you're not ready to be an open source contributor; that your skills aren't nearly good enough to contribute. What could you possibly offer?

We assure you that the little voice in your head is wrong.

Being a contributor doesn't just mean writing code. Equally important contributions include: writing or proof-reading documentation, suggesting or implementing tests, or even giving feedback about the project (including giving feedback about the contribution process). If you're coming to the project with fresh eyes, you might see the errors and assumptions that seasoned contributors have glossed over. If you can write any code at all, you can contribute code to open source. We are constantly trying out new skills, making mistakes, and learning from those mistakes. That's how we all improve and we are happy to help others learn.

This disclaimer was adapted from the MetPy project.

Citing PyGMT

PyGMT is a community developed project. See the AUTHORS.md file on GitHub for a list of the people involved and a definition of the term "PyGMT Developers". Feel free to cite our work in your research using the following BibTeX:

@software{
  pygmt_2024_11062720,
  author       = {Tian, Dongdong and
                  Uieda, Leonardo and
                  Leong, Wei Ji and
                  Fröhlich, Yvonne and
                  Schlitzer, William and
                  Grund, Michael and
                  Jones, Max and
                  Toney, Liam and
                  Yao, Jiayuan and
                  Magen, Yohai and
                  Tong, Jing-Hui and
                  Materna, Kathryn and
                  Belem, Andre and
                  Newton, Tyler and
                  Anant, Abhishek and
                  Ziebarth, Malte and
                  Quinn, Jamie and
                  Wessel, Paul},
  title        = {{PyGMT: A Python interface for the Generic Mapping Tools}},
  month        = may,
  year         = 2024,
  publisher    = {Zenodo},
  version      = {0.12.0},
  doi          = {10.5281/zenodo.11062720},
  url          = {https://doi.org/10.5281/zenodo.11062720}
}

To cite a specific version of PyGMT, go to our Zenodo page at https://doi.org/10.5281/zenodo.3781524 and use the "Export to BibTeX" function there. It is also strongly recommended to cite the GMT 6 paper (which PyGMT wraps around). Note that some modules like dimfilter, surface, and x2sys also have their dedicated citations. Further information for all these can be found at https://www.generic-mapping-tools.org/cite.

License

PyGMT is free software: you can redistribute it and/or modify it under the terms of the BSD 3-clause License. A copy of this license is provided in LICENSE.txt.

Support

The development of PyGMT has been supported by NSF grants OCE-1558403 and EAR-1948603.

Related projects

Other official wrappers for GMT:

  • GMT.jl: A Julia wrapper for GMT.
  • gmtmex: A Matlab/Octave wrapper for GMT.

Other non-official Python wrappers for GMT (not maintained):

Minimum supported versions

PyGMT has adopted SPEC 0 alongside the rest of the Scientific Python ecosystem, and therefore:

  • Support for Python versions be dropped 3 years after their initial release.
  • Support for core package dependencies (NumPy/Pandas/Xarray) be dropped 2 years after their initial release.

Similarly, the PyGMT team has decided to discontinue support for GMT versions 3 years after their initial release.

Please see Minimum Supported Versions for the minimum supported versions of GMT, Python and core package dependencies.

pygmt's People

Contributors

akshmakov avatar aliciaha1997 avatar alperen-kilic avatar andrebelem avatar arleaman avatar carocamargo avatar claudiodsf avatar core-man avatar daroari avatar dependabot[bot] avatar hemmelig avatar itsabhianant avatar jamiejquinn avatar jhtong33 avatar kmaterna avatar leouieda avatar liamtoney avatar maxrjones avatar michaeineumann avatar michaelgrund avatar noorbuchi avatar obaney avatar seisman avatar srijac avatar tjnewton avatar weiji14 avatar willschlitzer avatar xdshivani avatar yohaimagen avatar yvonnefroehlich avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pygmt's Issues

Install problems

Hi Leo

I'm using Python3.5 on OSX.

I first tried to install via Anaconda. The install looked ok, but when I tried import gmt, it said the module was not found.

So instead, I downloaded the source from git and installed using pip. This seems to go okay, but when I try: import gmt, I get the following error:

Traceback (most recent call last):
File "", line 1, in
File "/Users/sph1r17/anaconda/lib/python3.5/site-packages/gmt/init.py", line 18, in
_begin()
File "/Users/sph1r17/anaconda/lib/python3.5/site-packages/gmt/session_management.py", line 20, in begin
with APISession() as session:
File "/Users/sph1r17/anaconda/lib/python3.5/site-packages/gmt/clib/core.py", line 205, in enter
self.session_id = create_session()
File "/Users/sph1r17/anaconda/lib/python3.5/site-packages/gmt/clib/core.py", line 135, in create_session
libgmt = load_libgmt()
File "/Users/sph1r17/anaconda/lib/python3.5/site-packages/gmt/clib/core.py", line 32, in load_libgmt
libgmt = ctypes.CDLL('.'.join(['libgmt', lib_ext]))
File "/Users/sph1r17/anaconda/lib/python3.5/ctypes/init.py", line 347, in init
self._handle = _dlopen(self._name, mode)
OSError: dlopen(libgmt.dylib, 6): image not found

Utility functions for creating temporary files

A lot of the clib tests need dummy file names for dumping output and then reading it out. Some are using NamedTemporaryFile but some set the file name by hand. They all need to create a closed file so that GMT can write to it. It also needs to be deleted once the function is done with the file. Ideally, it should be cleaned even if an exception occurs. Using plain NamedTemporaryFile won't work because it keeps the file open for writing in Python.

Create a GMTTempFile context manager class in gmt/utils.py that creates a temp file with NamedTemporaryFile and closes it immediately. It should include the prefix gmt-python- and suffix that is user specified (optional). When exiting, delete the file using os.remove. The class should include a method read to open and return the entire contents of the file. It should also replace the tabs that GMT uses with spaces to make it more Python friendly (with an options to keep them).

Make gmt.clib functions into methods of APISession

No point in having this class if all it's good for is creating and destroying the session. It might as well define the C API functions and pass in the "session" argument for us. This would also make the clib code more testable because we can mock things like the OS name and check that exceptions are being raised.

Implement show function

Calls psconvert to get a PNG and insert it into the notebook.

For now, save to a temp file and load it. Later on can get data directly from psconvert.

GMT installation clashes with SHTOOLS

Hi,
I very much appriciate your efforts and would welcome any further developments in this direction. When trying gmt python I followed the guidelines available and could install it without a problem. However, a colleague could not run his scripts any more since gmt python changed some packages, it appears. Judging from error messages it traces back to the fftw part that is used by both gmt and shtools.

Best,
Konwill

Replace asserts with our custom exceptions

#39 introduces custom exceptions for GMT/Python.
We need to search for all assert statements (not counting the tests) and raise our exceptions instead when checking inputs and outputs.
We may need to define some new exceptions.

PackageNotFoundError

Hi guys,
Just wanted to install gmt following the install recipe but

conda install gmt -c conda-forge/label/dev

returns

PackageNotFoundError: Packages missing in current channels:

  • gmt -> blas 1.1 openblas
  • gmt -> dcw-gmt
  • gmt -> fftw
  • gmt -> ghostscript
  • gmt -> gshhg-gmt
  • gmt -> @blas_openblas

We have searched for the packages in the following channels:

what should I do ?
thanks

Intruct people to create a conda env

Add instructions to Install docs about creating a conda environment for the install.
Mixing packages from the defaults channel and conda-forge can cause problems with incompatible shared libraries (see #30 and #32).

List of GMT aliases

Paul compiled this list of aliases and GMT vocabulary. We should include this somewhere in the docs and in the code somewhere to avoid repetition.

GMT Vocabulary for Python Aliases

The idea is to agree on a set of nouns that can serve as the Python aliases for GMT common options as well as commonly used options (such as pens, color).

Common options:

Option Alias
B frame
Bx,By,Bz axes settings
J projection, proj
P portrait [PS only - goes away I think]
R region
U timestamp
V verbosity
X xshift
y yshift
b binary_in, binary_out, binary
d nodata
e search
f coltypes,type?
g gap
h header
i cols_in
n bc
o cols_out
p view
r reg, registration
s skip
t transparency
x cores

Common themes that could use fixed aliases

Option Alias
G fill,color,clip
W pen, thickness,color,style
C cpt
F font=, justification=, offset=,

Wrapper for 'gmt which'

The wrapper should be a function in gmt/modules.py. See how other wrappers are built in gmt/base_plotting.py.

This module will be useful to download the new GMT tutorial and topography data using the @filename syntax. For example, running for the first time gmt which @tut_quakes.ngdc will download the data to the GMT hidden folder and provide the file name to stdout. We will use this to make a higher level gmt.datasets package that loads these data as numpy arrays and xarray grids.

The wrapper will need to capture stdout and return it. See discussion on #43

@rpath/libicui18n.58.dylib Reason: image not found

Hi all,
I have installed the code through anaconda (python 3.5) and I am getting the next error:

>> import gmt

OSError: dlopen(libgmt.dylib, 6): Library not loaded: @rpath/libicui18n.58.dylib
  Referenced from: /opt/anaconda/lib/libgdal.20.dylib
  Reason: image not found

Any ideas how can I fix this issue? I am working on Mac OS X.

Thanks in advance,
Esteban

GMT API callback to get error messages

Paul implemented a new API function that might be useful. For now, we only include the error code in the traceback while GMT prints the error message to stderr. It would be better to capture that message and include it in the exceptions.

EXTERN_MSC int GMT_Handle_Messages (void *API, unsigned int mode, unsigned int method, void *dest);

mode can be GMT_LOG_OFF, GMT_LOG_ONCE, or GMT_LOG_SET. First resets logging back to stderr (which is the default), ONCE sets logging from the next module to go to dest, then resets to stderr, while SET sets logging to go to dest until changed (or until session ends).
method is either GMT_IS_FILE, GMT_IS_STREAM, or GMT_IS_FDESC. So, to turn logging on to a file this.log for the next module, try GMT_Handle_Messages (API, GMT_LOG_ONCE, GMT_IS_FILE, “this.log”);

Could include a call using GMT_LOG_SET into gmt.clib.LibGMT to capture the messages.

Implement argument in Figure.savefig to display figure

Add an extra argument (show=False) to Figure.savefig to open the figure in an external viewer (use launch_external_viewer). This operation is non-blocking so the script will keep going. This is a way for scripts to display the figure without relying on Figure.show, which would not work because the temp directory with the figure is cleaned when the Figure object is deleted. It makes more sense because scripts will want a figure file to be saved, unlike in notebooks where you want to see them inline most of the time.

Create an exception for invalid input

Right now, both invalid inputs and failures (status != 0) raise GMTCLibError. This doesn't help with the testing because I can't tell which one was raised. It would be better to have a GMTCLibInvalidInput (and a GMTInvalidInput as well) exception to keep things separate.

All functions/methods in gmt/clib/ would need to modified to raise this exception instead. The tests in gmt/tests/test_clib.py would need to modified to check for this exception.

Wrapper for psconvert

Need this to make gmt.end insert a plot into the notebook (call psconvert to get a PNG and use IPython.display.Image).

gmt.figure shouldn't require a prefix

The prefix sets the file name of the output figure. This shouldn't be required in Python because one might not produce an output plot in Jupyter notebook. Could have it set to some default name.

libgmt argument should be first for clib functions

Almost every function in gmt.clib.core requires the libgmt argument (a ctypes.CDLL instance). Currently, it's the last argument. That makes it hard to implement optional arguments or **kwargs in these functions.

It should the first argument, followed by session.

Support for Windows

You have mentioned that this has been tested in Unix and OSX. I tried intalling in Windows through cloning the repo. However when I import gmt in Jupyter, it gave me the following error.

GMTOSError: Unknown operating system: win32

Any solution for a Windows support?

Easier to read aliases in docstrings

Right now, the parameter aliases (region for R, projection for J) are listed above the parameter descriptions. This is a bit hard to read because you have to go back and forth between the alias list and descriptions.

It would be better for the parameter names to be listed as the long alias and include the original 1 letter name next to it.

For example, this is how it is now:

Aliases
-------
* J = projection

Parameters
----------
J : string
    The projection bla bla bla

and what I would like to see is:

Aliases
-------
* J = projection

Parameters
----------
projection (J) : string
    The projection bla bla bla

This can be in the fmt_docstring decorator in gmt/decorators.py. It might make it easier to define all descriptions of the GMT module arguments outside of the docstring (like we do already for the common ones, like J and R). The Python specific arguments, usually for passing in data, don't have aliases and could be specified normally on the docstring.

Wrapper for gmt info

Create a wrapper function for gmt info. Data input should be a file name data='some_file.txt'. Doesn't really make much sense to read in numpy arrays for this because most of it can be done using numpy functions.

See how other modules are wrapped, for example in gmt/base_plotting.py.

Generate no figure file (for use in the notebook)

When using the Jupyter notebook, one doesn't necessarily want a figure file on disk in the end. The embedded PNG in the notebook is enough.

There needs to be an option for begin, end, figure to say that I don't want any outputs when calling end.

gmt.show() not working in ipython console

gmt.show() can display figure in ipython notebook but not in ipython console.

$ ipython
Python 3.6.1 |Anaconda custom (64-bit)| (default, May 11 2017, 13:09:58) 
Type 'copyright', 'credits' or 'license' for more information
IPython 6.1.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import gmt

In [2]: gmt.figure()

In [3]: gmt.pscoast(R='-90/-70/0/20', J='M6i', G='chocolate',
   ...:             S='skyblue', P=True, B='afg')
   ...:             

In [4]: gmt.show()
<IPython.core.display.Image object>

In [5]: 

It will be better if gmt.show() can open a new figure window just like what matplotlib.pyplot.show does.

OSError Install issue: won't open the gmt library, image not found

Using Mac os x sierra and the latest version of conda I followed everything on the installation page
https://genericmappingtools.github.io/gmt-python/install.html including setting LD_LIBRARY_PATH in .bashrc to my anaconda library and get this error

Python 3.6.2 |Anaconda custom (x86_64)| (default, Jul 20 2017, 13:14:59) 
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import gmt
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/XXXX/anaconda3/lib/python3.6/site-packages/gmt/__init__.py", line 18, in <module>
    _begin()
  File "/Users/XXXX/anaconda3/lib/python3.6/site-packages/gmt/session_management.py", line 20, in begin
    with APISession() as session:
  File "/Users/XXXX/anaconda3/lib/python3.6/site-packages/gmt/clib/core.py", line 205, in __enter__
    self.session_id = create_session()
  File "/Users/XXXX/anaconda3/lib/python3.6/site-packages/gmt/clib/core.py", line 135, in create_session
    libgmt = load_libgmt()
  File "/Users/XXXX/anaconda3/lib/python3.6/site-packages/gmt/clib/core.py", line 32, in load_libgmt
    libgmt = ctypes.CDLL('.'.join(['libgmt', lib_ext]))
  File "/Users/XXXX/anaconda3/lib/python3.6/ctypes/__init__.py", line 348, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: dlopen(libgmt.dylib, 6): Library not loaded: @rpath/libicui18n.58.dylib
  Referenced from: /Users/XXXX/anaconda3/lib/libgdal.20.dylib
  Reason: image not found

Here's what my .bashrc looks like

PS1="\w ";
export PS1

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$HOME/anaconda3/lib

Also I have conda-forge set as the priority conda channel in .condarc. According to this https://conda-forge.org/docs/conda-forge_gotchas.html conda forge uses icu 56. In the error however my system is trying to use icu 58? I'm not sure what I am missing, any help?

**edit: when I created a new conda environment and recreated all the steps, it works. ALSO, i had to reinstall jupyter and nb_conda in this environment in order to get it working in a notebook

Include links to download the tutorial notebooks

The tutorials are implemented as Jupyter notebooks and converted to rst using nbsphinx. It would be great to include a link to download the original notebook so that people can run it on their machine.

We should not link to the Github source because the documentation pages won't always reflect the most current master. Instead, the notebook file should be included with the generated html and the link should be to that.

Creating and writing to virtual files

This is what is needed to get data in and out of GMT. This is a sample of the API usage in C:

if ((V_in = GMT_Create_Data (API, GMT_IS_VECTOR, GMT_IS_POINT, 0, dim, NULL, NULL, 0, 0, NULL)) == NULL) exit (EXIT_FAILURE);
dim[0] = 3;	/* Want three output columns [we will share the first two with input] */
if ((V_out = GMT_Create_Data (API, GMT_IS_VECTOR, GMT_IS_POINT, 0, dim, NULL, NULL, 0, 0, NULL)) == NULL) exit (EXIT_FAILURE);
/* Allocate three custum vectors using malloc; here of length 7 (i.e., >= 5) */
x = malloc (7*sizeof(double));	y = malloc (7*sizeof(double));	z = malloc (7*sizeof(int));
/* Hook these up to our containers, reusing x,y as both in and out x/y vectors */
GMT_Put_Vector (API, V_in,  GMT_X, GMT_DOUBLE, x);
GMT_Put_Vector (API, V_in,  GMT_Y, GMT_DOUBLE, y);
GMT_Put_Vector (API, V_out, GMT_X, GMT_DOUBLE, x);
GMT_Put_Vector (API, V_out, GMT_Y, GMT_DOUBLE, y);
GMT_Put_Vector (API, V_out, GMT_Z, GMT_INT,    z);
V_in->n_rows = V_out->n_rows = 5;	/* Must specify how many input points we will simulate */
/* Associate the grid with a virtual input file */
GMT_Open_VirtualFile (API, GMT_IS_GRID, GMT_IS_SURFACE, GMT_IN, G_in, grid);
/* Associate our input data vectors with a virtual input file */
GMT_Open_VirtualFile (API, GMT_IS_VECTOR, GMT_IS_POINT, GMT_IN, V_in, input);
/* Associate our output data vectors with a virtual output file */
GMT_Open_VirtualFile (API, GMT_IS_VECTOR, GMT_IS_POINT, GMT_OUT, V_out, output);
/* Close the three virtual files */
GMT_Close_VirtualFile (API, grid);
GMT_Close_VirtualFile (API, input);
GMT_Close_VirtualFile (API, output);

So I'll need to wrap:

  • GMT_Create_Data
  • GMT_Put_Vector
  • GMT_Put_Matrix
  • GMT_Get_Vector
  • GMT_Get_Matrix
  • GMT_Open_VirtualFile
  • GMT_Close_VirtualFile

Will also need to define all the constants.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.