Skip to content

Commit 854a4e9

Browse files
authored
Merge branch 'master' into update-authors
2 parents e5bf2d2 + 2efcbba commit 854a4e9

File tree

13 files changed

+483
-109
lines changed

13 files changed

+483
-109
lines changed

.github/workflows/ci_tests.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,9 @@ jobs:
8989
run: |
9090
mkdir -p ~/.gmt
9191
mv .gmt/* ~/.gmt
92-
ls -lh ~/.gmt
92+
# Change modification times of the two files, so GMT won't refresh it
93+
touch ~/.gmt/server/gmt_data_server.txt ~/.gmt/server/gmt_hash_server.txt
94+
ls -lhR ~/.gmt
9395
9496
# Install the package that we want to test
9597
- name: Install the package

.github/workflows/ci_tests_dev.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,9 @@ jobs:
108108
run: |
109109
mkdir -p ~/.gmt
110110
mv .gmt/* ~/.gmt
111-
ls -lh ~/.gmt
111+
# Change modification times of the two files, so GMT won't refresh it
112+
touch ~/.gmt/server/gmt_data_server.txt ~/.gmt/server/gmt_hash_server.txt
113+
ls -lhR ~/.gmt
112114
113115
# Install the package that we want to test
114116
- name: Install the package

doc/api/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Color palette table generation:
4444
.. autosummary::
4545
:toctree: generated
4646

47+
grd2cpt
4748
makecpt
4849

4950
Saving and displaying the figure:

doc/install.rst

Lines changed: 98 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -14,34 +14,64 @@ Installing
1414
<https://forum.generic-mapping-tools.org/c/questions/pygmt-q-a>`__.
1515

1616

17+
Quickstart
18+
----------
19+
20+
The fastest way to install PyGMT is with the
21+
`conda <https://docs.conda.io/projects/conda/en/latest/user-guide/index.html>`__
22+
package manager which takes care of setting up a virtual environment, as well
23+
as the installation of GMT and all the dependencies PyGMT depends on::
24+
25+
conda create --name pygmt --channel conda-forge pygmt
26+
27+
To activate the virtual environment, you can do::
28+
29+
conda activate pygmt
30+
31+
After this, check that everything works by running the following in a Python
32+
interpreter (e.g. in a Jupyter notebook)::
33+
34+
import pygmt
35+
pygmt.show_versions()
36+
37+
You are now ready to make you first figure!
38+
Start by looking at the tutorials on our sidebar, good luck!
39+
40+
.. note::
41+
42+
The sections below provide more detailed, step by step instructions to
43+
installing and testing PyGMT for those who may have a slightly different
44+
setup.
45+
1746
Which Python?
1847
-------------
1948

20-
You'll need **Python 3.7 or greater** to run PyGMT. Old Python versions may
21-
work, but there is no guarantee that PyGMT will work as expected with old versions.
49+
PyGMT is tested to run on **Python 3.7 or greater**. Older Python versions may
50+
work, but there is no guarantee that PyGMT will behave as expected.
2251

23-
We recommend using the `Anaconda <https://www.anaconda.com/distribution>`__ Python
24-
distribution to ensure you have all dependencies installed and the ``conda``
25-
package manager available.
52+
We recommend using the `Anaconda <https://www.anaconda.com/distribution>`__
53+
Python distribution to ensure you have all dependencies installed and the
54+
``conda`` package manager available.
2655
Installing Anaconda does not require administrative rights to your computer and
2756
doesn't interfere with any other Python installations in your system.
2857

2958

3059
Which GMT?
3160
----------
3261

33-
PyGMT requires Generic Mapping Tools (GMT) version 6 as a minimum, which is the latest
34-
released version that can be found at
62+
PyGMT requires Generic Mapping Tools (GMT) version 6 as a minimum, which is the
63+
latest released version that can be found at
3564
the `GMT official site <https://www.generic-mapping-tools.org>`__.
36-
We need the latest GMT (>=6.1.1) since there are many changes being made to GMT itself in
37-
response to the development of PyGMT, mainly the new
65+
We need the latest GMT (>=6.1.1) since there are many changes being made to GMT
66+
itself in response to the development of PyGMT, mainly the new
3867
`modern execution mode <https://docs.generic-mapping-tools.org/latest/cookbook/introduction.html#modern-and-classic-mode>`__.
3968

40-
Compiled conda packages of GMT for Linux, macOS and Windows are provided through
41-
`conda-forge <https://anaconda.org/conda-forge/gmt>`__.
69+
Compiled conda packages of GMT for Linux, macOS and Windows are provided
70+
through `conda-forge <https://anaconda.org/conda-forge/gmt>`__.
4271
Advanced users can also
4372
`build GMT from source <https://github.com/GenericMappingTools/gmt/blob/master/BUILDING.md>`__
44-
instead, which is not so recommended but we would love to get feedback from anyone who tries.
73+
instead, which is not so recommended but we would love to get feedback from
74+
anyone who tries.
4575

4676
We recommend following the instructions further on to install GMT 6.
4777

@@ -58,61 +88,97 @@ PyGMT requires the following libraries:
5888

5989
The following are optional (but recommended) dependencies:
6090

61-
* `IPython <https://ipython.org/>`__: For embedding the figures in Jupyter notebooks.
91+
* `IPython <https://ipython.org/>`__: For embedding the figures in Jupyter
92+
notebooks.
6293

6394

6495
Installing GMT and other dependencies
6596
-------------------------------------
6697

67-
Before installing PyGMT, we must install GMT itself along with the other dependencies.
68-
The easiest way to do this is using the ``conda`` package manager.
98+
Before installing PyGMT, we must install GMT itself along with the other
99+
dependencies. The easiest way to do this is via the ``conda`` package manager.
69100
We recommend working in an isolated
70101
`conda environment <https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html>`__
71-
to avoid issues with competing versions of its dependencies.
102+
to avoid issues with conflicting versions of dependencies.
72103

73104
First, we must configure conda to get packages from the
74105
`conda-forge channel <https://conda-forge.org/>`__::
75106

76107
conda config --prepend channels conda-forge
77108

78-
Now we can create a new conda environment with Python and all our dependencies installed
79-
(we'll call it ``pygmt`` but you can change it to whatever you want)::
109+
Now we can create a new conda environment with Python and all our dependencies
110+
installed (we'll call it ``pygmt`` but feel free to change it to whatever you
111+
want)::
80112

81113
conda create --name pygmt python=3.9 pip numpy pandas xarray netcdf4 packaging gmt
82114

83-
Activate the environment by running::
115+
Activate the environment by running the following (**do not forget this step!**)::
84116

85117
conda activate pygmt
86118

87-
From now on, all commands will take place inside the conda virtual environment and won't
88-
affect your default installation.
119+
From now on, all commands will take place inside the conda virtual environment
120+
called 'pygmt' and won't affect your default 'base' installation.
89121

90122

91123
Installing PyGMT
92124
----------------
93125

94-
Now that you have GMT installed and your conda environment activated, you can
95-
use ``conda`` to install the latest release of PyGMT from `conda-forge <https://anaconda.org/conda-forge/pygmt>`__::
126+
Now that you have GMT installed and your conda virtual environment activated,
127+
you can install PyGMT using any of the following methods:
128+
129+
Using conda (recommended)
130+
~~~~~~~~~~~~~~~~~~~~~~~~~
131+
132+
This installs the latest stable release of PyGMT from
133+
`conda-forge <https://anaconda.org/conda-forge/pygmt>`__::
96134

97135
conda install pygmt
98136

99-
or use ``pip`` to install from `PyPI <https://pypi.org/project/pygmt>`__::
137+
Using pip
138+
~~~~~~~~~
139+
140+
This installs the latest stable release from
141+
`PyPI <https://pypi.org/project/pygmt>`__::
100142

101143
pip install pygmt
102144

103-
Alternatively, you can install the development version from the GitHub repository::
145+
Alternatively, you can install the latest development version from
146+
`TestPyPI <https://test.pypi.org/project/pygmt>`__::
147+
148+
pip install --pre --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple pygmt
104149

105-
pip install https://github.com/GenericMappingTools/pygmt/archive/master.zip
150+
or from PyGMT's `GitHub repository <https://github.com/GenericMappingTools/pygmt>`__
151+
(slower as it downloads the whole archive)::
106152

107-
This will allow you to use the ``pygmt`` library from Python.
153+
pip install git+https://github.com/GenericMappingTools/pygmt.git#egg=pygmt
154+
155+
Any of the above methods (conda/pip) should allow you to use the ``pygmt``
156+
library from Python.
108157

109158

110159
Testing your install
111160
--------------------
112161

162+
Quick check
163+
~~~~~~~~~~~
164+
165+
To ensure that PyGMT and its depedencies are installed correctly, run the
166+
following in your Python interpreter::
167+
168+
import pygmt
169+
pygmt.show_versions()
170+
171+
Or run this in the command line::
172+
173+
python -c "import pygmt; pygmt.show_versions()"
174+
175+
176+
Full test (optional)
177+
~~~~~~~~~~~~~~~~~~~~
178+
113179
PyGMT ships with a full test suite.
114-
You can run our tests after you install it but you will need a few extra dependencies as
115-
well (be sure to have your conda env activated)::
180+
You can run our tests after you install it but you will need a few extra
181+
dependencies as well (be sure to have your conda environment activated)::
116182

117183
conda install pytest pytest-mpl ipython
118184

@@ -132,9 +198,9 @@ This can happen if you have multiple versions of GMT installed.
132198

133199
You can tell PyGMT exactly where to look for ``libgmt`` by setting the
134200
``GMT_LIBRARY_PATH`` environment variable.
135-
This should be set to the directory where ``libgmt.so``, ``libgmt.dylib`` or ``gmt.dll``
136-
can be found for Linux, macOS and Windows respectively.
137-
e.g. in a terminal run::
201+
This should be set to the directory where ``libgmt.so``, ``libgmt.dylib`` or
202+
``gmt.dll`` can be found for Linux, macOS and Windows respectively.
203+
e.g. on a command line, run::
138204

139205
# Linux/macOS
140206
export GMT_LIBRARY_PATH=$HOME/anaconda3/envs/pygmt/lib

pygmt/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from pygmt.session_management import end as _end
2020
from pygmt.src import (
2121
blockmedian,
22+
grd2cpt,
2223
grdcut,
2324
grdfilter,
2425
grdinfo,

pygmt/clib/loading.py

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
"""
77
import ctypes
88
import os
9+
import subprocess as sp
910
import sys
1011
from ctypes.util import find_library
1112

@@ -31,9 +32,10 @@ def load_libgmt():
3132
If there was any problem loading the library (couldn't find it or
3233
couldn't access the functions).
3334
"""
34-
lib_fullnames = clib_full_names()
35+
lib_fullnames = []
3536
error = True
36-
for libname in lib_fullnames:
37+
for libname in clib_full_names():
38+
lib_fullnames.append(libname)
3739
try:
3840
libgmt = ctypes.CDLL(libname)
3941
check_libgmt(libgmt)
@@ -72,7 +74,7 @@ def clib_names(os_name):
7274
elif os_name.startswith("freebsd"): # FreeBSD
7375
libnames = ["libgmt.so"]
7476
else:
75-
raise GMTOSError(f'Operating system "{sys.platform}" not supported.')
77+
raise GMTOSError(f'Operating system "{os_name}" not supported.')
7678
return libnames
7779

7880

@@ -86,24 +88,45 @@ def clib_full_names(env=None):
8688
A dictionary containing the environment variables. If ``None``, will
8789
default to ``os.environ``.
8890
89-
Returns
90-
-------
91+
Yields
92+
------
9193
lib_fullnames: list of str
9294
List of possible full names of GMT's shared library.
9395
"""
9496
if env is None:
9597
env = os.environ
98+
9699
libnames = clib_names(os_name=sys.platform) # e.g. libgmt.so, libgmt.dylib, gmt.dll
97-
libpath = env.get("GMT_LIBRARY_PATH", "") # e.g. $HOME/miniconda/envs/pygmt/lib
98100

99-
lib_fullnames = [os.path.join(libpath, libname) for libname in libnames]
100-
# Search for DLLs in PATH if GMT_LIBRARY_PATH is not defined [Windows only]
101-
if not libpath and sys.platform == "win32":
101+
# list of libraries paths to search, sort by priority from high to low
102+
# Search for libraries in GMT_LIBRARY_PATH if defined.
103+
libpath = env.get("GMT_LIBRARY_PATH", "") # e.g. $HOME/miniconda/envs/pygmt/lib
104+
if libpath:
105+
for libname in libnames:
106+
libfullpath = os.path.join(libpath, libname)
107+
if os.path.exists(libfullpath):
108+
yield libfullpath
109+
110+
# Search for the library returned by command "gmt --show-library"
111+
try:
112+
libfullpath = sp.check_output(
113+
["gmt", "--show-library"], encoding="utf-8"
114+
).rstrip("\n")
115+
assert os.path.exists(libfullpath)
116+
yield libfullpath
117+
except (FileNotFoundError, AssertionError): # command not found
118+
pass
119+
120+
# Search for DLLs in PATH (done by calling "find_library")
121+
if sys.platform == "win32":
102122
for libname in libnames:
103123
libfullpath = find_library(libname)
104124
if libfullpath:
105-
lib_fullnames.append(libfullpath)
106-
return lib_fullnames
125+
yield libfullpath
126+
127+
# Search for library names in the system default path [the lowest priority]
128+
for libname in libnames:
129+
yield libname
107130

108131

109132
def check_libgmt(libgmt):
@@ -128,10 +151,5 @@ def check_libgmt(libgmt):
128151
functions = ["Create_Session", "Get_Enum", "Call_Module", "Destroy_Session"]
129152
for func in functions:
130153
if not hasattr(libgmt, "GMT_" + func):
131-
msg = " ".join(
132-
[
133-
"Error loading libgmt.",
134-
"Couldn't access function GMT_{}.".format(func),
135-
]
136-
)
154+
msg = f"Error loading libgmt. Couldn't access function GMT_{func}."
137155
raise GMTCLibError(msg)

0 commit comments

Comments
 (0)