diff --git a/.gitignore b/.gitignore index 5fae9448de5..c3bbdc79eb4 100644 --- a/.gitignore +++ b/.gitignore @@ -27,14 +27,14 @@ tmp-test-dir-with-unique-name/ # Sphinx documentation doc/api/generated/ doc/_build/ +doc/intro/ +doc/tutorials/ doc/gallery/ doc/projections/ -doc/tutorials/ -doc/get_started/ # doc/sg_execution_time.rst is auto-generated by Sphinx-Gallery doc/sg_execution_times.rst -# Jupyter Notebook +# Jupyter notebook .ipynb_checkpoints/ # Visual Studio Code diff --git a/doc/Makefile b/doc/Makefile index aab41e56727..63ecd10f5ac 100644 --- a/doc/Makefile +++ b/doc/Makefile @@ -55,7 +55,7 @@ server: clean: rm -rf $(BUILDDIR) rm -rf api/generated - rm -rf gallery + rm -rf intro rm -rf tutorials - rm -rf get_started + rm -rf gallery rm -rf projections diff --git a/doc/conf.py b/doc/conf.py index fc26641bd83..1586601804d 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -11,7 +11,7 @@ from pygmt.sphinx_gallery import PyGMTScraper from sphinx_gallery.sorting import ExampleTitleSortKey, ExplicitOrder -# Dictionary for dependency name and minimum required version. +# Dictionary for dependency name and minimum required versions requirements = { Requirement(requirement).name: str(Requirement(requirement).specifier) for requirement in importlib.metadata.requires("pygmt") @@ -50,7 +50,8 @@ # Auto-generate header anchors with MyST parser myst_heading_anchors = 4 -# reference: https://myst-parser.readthedocs.io/en/latest/syntax/optional.html +# MyST extensions +# Reference: https://myst-parser.readthedocs.io/en/latest/syntax/optional.html myst_enable_extensions = [ "attrs_inline", # Allow inline attributes after images "colon_fence", # Allow code fences using colons @@ -61,26 +62,25 @@ "requires": requirements, } -# MyST-NB configurations. +# Configure MyST-NB # Reference: https://myst-nb.readthedocs.io/en/latest/configuration.html -nb_render_markdown_format = "myst" # The format to use for text/markdown rendering +nb_render_markdown_format = "myst" # Format for text/markdown rendering -# Make the list of returns arguments and attributes render the same as the -# parameters list +# Render the return argument and attribute lists in the same way as the parameter lists napoleon_use_rtype = False napoleon_use_ivar = True -# sphinx_auto_typehints +# Configure sphinx_auto_typehints typehints_defaults = "comma" -# configure links to GMT docs +# Define links to GMT docs extlinks = { "gmt-docs": ("https://docs.generic-mapping-tools.org/6.5/%s", None), "gmt-term": ("https://docs.generic-mapping-tools.org/6.5/gmt.conf#term-%s", "%s"), "gmt-datasets": ("https://www.generic-mapping-tools.org/remote-datasets/%s", None), } -# intersphinx configuration +# Configure intersphinx intersphinx_mapping = { "contextily": ("https://contextily.readthedocs.io/en/stable/", None), "geopandas": ("https://geopandas.org/en/stable/", None), @@ -93,25 +93,28 @@ "xyzservices": ("https://xyzservices.readthedocs.io/en/stable", None), } -# options for sphinx-copybutton -# https://sphinx-copybutton.readthedocs.io +# Configure sphinx-copybutton +# Reference: https://sphinx-copybutton.readthedocs.io copybutton_prompt_text = r">>> |\.\.\. " copybutton_prompt_is_regexp = True copybutton_only_copy_prompt_lines = True copybutton_remove_prompts = True sphinx_gallery_conf = { - # path to your examples scripts + # Set paths to your examples scripts "examples_dirs": [ - "../examples/gallery", + "../examples/intro", "../examples/tutorials", - "../examples/get_started", + "../examples/gallery", "../examples/projections", ], - # path where to save gallery generated examples - "gallery_dirs": ["gallery", "tutorials", "get_started", "projections"], + # Set paths where to save the generated examples + "gallery_dirs": ["intro", "tutorials", "gallery", "projections"], "subsection_order": ExplicitOrder( [ + "../examples/intro", + "../examples/tutorials/basics", + "../examples/tutorials/advanced", "../examples/gallery/maps", "../examples/gallery/lines", "../examples/gallery/symbols", @@ -127,53 +130,48 @@ "../examples/projections/misc", "../examples/projections/nongeo", "../examples/projections/table", - "../examples/tutorials/basics", - "../examples/tutorials/advanced", - "../examples/get_started", ] ), # Pattern to search for example files "filename_pattern": r"\.py", # Remove the "Download all examples" button from the top level gallery "download_all_examples": False, - # Sort gallery example by file name instead of number of lines (default) + # Sort gallery examples by the file names instead of number of lines [Default] "within_subsection_order": ExampleTitleSortKey, - # directory where function granular galleries are stored + # Directory where function granular galleries are stored "backreferences_dir": "api/generated/backreferences", - # Modules for which function level galleries are created. In - # this case sphinx_gallery and numpy in a tuple of strings. - "doc_module": "pygmt", + # Modules for which function level galleries are created (given as tuple of strings) + "doc_module": ("pygmt",), # Insert links to documentation of objects in the examples "reference_url": {"pygmt": None}, "image_scrapers": (PyGMTScraper(),), - # Removes configuration comments from scripts + # Remove configuration comments from scripts "remove_config_comments": True, - # Disable "nested_sections" (default is True), to - # generate only a single index file for the whole gallery. - # This is a new feature up on Sphinx-Gallery 0.11.0. + # Disable "nested_sections" [Default is True], to generate only a single index file + # for the whole gallery. This is a new feature up on Sphinx-Gallery 0.11.0. "nested_sections": False, } -# Sphinx project configuration +# Configure Sphinx project templates_path = ["_templates"] exclude_patterns = [ "_build", "**.ipynb_checkpoints", # Workaround from https://github.com/executablebooks/MyST-NB/issues/363 to prevent - # myst-nb from parsing the .ipynb and .py files generated by sphinx-gallery. - "gallery/**.ipynb", + # MyST-NB from parsing the .ipynb and .py files generated by Sphinx-Gallery. + "intro/**.ipynb", "tutorials/**.ipynb", - "get_started/**.ipynb", + "gallery/**.ipynb", "projections/**.ipynb", - "gallery/**.py", + "intro/**.py", "tutorials/**.py", - "get_started/**.py", + "gallery/**.py", "projections/**.py", ] source_suffix = ".rst" needs_sphinx = "1.8" -# The encoding of source files. +# Encoding of source files source_encoding = "utf-8-sig" root_doc = "index" @@ -183,11 +181,11 @@ copyright = f"2017-{year}, The PyGMT Developers" # noqa: A001 if len(__version__.split("+")) > 1 or __version__ == "unknown": version = "dev" - # Set base_url for stable version + # Set base URL for dev version html_baseurl = "https://pygmt.org/dev/" else: version = __version__ - # Set base_url for dev version + # Set base URL for stable version html_baseurl = "https://pygmt.org/latest/" release = __version__ @@ -205,7 +203,7 @@ html_show_sphinx = False html_show_copyright = True -# Theme config +# Configure theme html_theme = "sphinx_rtd_theme" html_theme_options = {} repository = "GenericMappingTools/pygmt" @@ -237,8 +235,7 @@ repository_url, ), ], - # Custom variables to enable "Improve this page"" and "Download notebook" - # links + # Custom variables to enable "Improve this page"" and "Download notebook" links "doc_path": "doc", "galleries": sphinx_gallery_conf["gallery_dirs"], "gallery_dir": dict( diff --git a/doc/index.md b/doc/index.md index 94b21a0d1fb..d04a4353182 100644 --- a/doc/index.md +++ b/doc/index.md @@ -22,7 +22,7 @@ overview.md install.md -get_started/index.rst +intro/index.rst ``` ```{toctree} @@ -39,7 +39,7 @@ external_resources.md ```{toctree} :maxdepth: 2 :hidden: -:caption: Reference documentation +:caption: Reference Documentation api/index.rst techref/index.md diff --git a/doc/install.md b/doc/install.md index 514af5dd91b..0283a95086c 100644 --- a/doc/install.md +++ b/doc/install.md @@ -47,13 +47,18 @@ conda activate pygmt After this, check that everything works by running the following in a Python interpreter (e.g., in a Jupyter notebook): -```python + +```{code-cell} ipython +--- +tags: [hide-output] +--- + import pygmt pygmt.show_versions() ``` -You are now ready to make you first figure! Start by looking at the tutorials on our -sidebar, good luck! +You are now ready to make your first figure! Start by looking at our [Intro](examples/intro/index.rst), +[Tutorials](examples/tutorials/index.rst), and [Gallery](examples/gallery/index.rst). Good luck! :::{note} The sections below provide more detailed, step by step instructions to install and test @@ -87,9 +92,9 @@ We recommend following the instructions further on to install GMT 6. PyGMT requires the following packages to be installed: -- [numpy](https://numpy.org) +- [NumPy](https://numpy.org) - [pandas](https://pandas.pydata.org) -- [xarray](https://xarray.dev/) +- [Xarray](https://xarray.dev/) - [netCDF4](https://unidata.github.io/netcdf4-python) - [packaging](https://packaging.pypa.io) diff --git a/examples/get_started/01_first_figure.py b/examples/intro/01_first_figure.py similarity index 100% rename from examples/get_started/01_first_figure.py rename to examples/intro/01_first_figure.py diff --git a/examples/get_started/02_contour_map.py b/examples/intro/02_contour_map.py similarity index 100% rename from examples/get_started/02_contour_map.py rename to examples/intro/02_contour_map.py diff --git a/examples/get_started/03_figure_element.py b/examples/intro/03_figure_element.py similarity index 100% rename from examples/get_started/03_figure_element.py rename to examples/intro/03_figure_element.py diff --git a/examples/get_started/04_table_inputs.py b/examples/intro/04_table_inputs.py similarity index 100% rename from examples/get_started/04_table_inputs.py rename to examples/intro/04_table_inputs.py diff --git a/examples/get_started/GALLERY_HEADER.rst b/examples/intro/GALLERY_HEADER.rst similarity index 100% rename from examples/get_started/GALLERY_HEADER.rst rename to examples/intro/GALLERY_HEADER.rst diff --git a/pygmt/datasets/tile_map.py b/pygmt/datasets/tile_map.py index 15331e256bb..c3322c39c36 100644 --- a/pygmt/datasets/tile_map.py +++ b/pygmt/datasets/tile_map.py @@ -126,23 +126,25 @@ def load_tile_map( >>> # CRS is set only if rioxarray is available >>> if hasattr(raster, "rio"): ... raster.rio.crs - CRS.from_epsg(3857) + CRS.from_wkt(...) """ if not _HAS_CONTEXTILY: - raise ImportError( + msg = ( "Package `contextily` is required to be installed to use this function. " "Please use `python -m pip install contextily` or " "`mamba install -c conda-forge contextily` to install the package." ) + raise ImportError(msg) contextily_kwargs = {} if zoom_adjust is not None: contextily_kwargs["zoom_adjust"] = zoom_adjust if Version(contextily.__version__) < Version("1.5.0"): - raise TypeError( + msg = ( "The `zoom_adjust` parameter requires `contextily>=1.5.0` to work. " "Please upgrade contextily, or manually set the `zoom` level instead." ) + raise TypeError(msg) west, east, south, north = region image, extent = contextily.bounds2img( diff --git a/pygmt/tests/test_clib_put_matrix.py b/pygmt/tests/test_clib_put_matrix.py index ff85a7430e8..cf1a71f99ec 100644 --- a/pygmt/tests/test_clib_put_matrix.py +++ b/pygmt/tests/test_clib_put_matrix.py @@ -7,6 +7,7 @@ import pytest import xarray as xr from pygmt import clib +from pygmt.clib.session import DTYPES_NUMERIC from pygmt.exceptions import GMTCLibError from pygmt.helpers import GMTTempFile from pygmt.tests.test_clib import mock @@ -17,7 +18,7 @@ def fixture_dtypes(): """ List of supported numpy dtypes. """ - return "int8 int16 int32 int64 uint8 uint16 uint32 uint64 float32 float64".split() + return [dtype for dtype in DTYPES_NUMERIC if dtype != np.timedelta64] @pytest.mark.benchmark diff --git a/pygmt/tests/test_clib_put_vector.py b/pygmt/tests/test_clib_put_vector.py index d42ee9afbba..7e1dd0d9310 100644 --- a/pygmt/tests/test_clib_put_vector.py +++ b/pygmt/tests/test_clib_put_vector.py @@ -9,6 +9,7 @@ import numpy.testing as npt import pytest from pygmt import clib +from pygmt.clib.session import DTYPES_NUMERIC from pygmt.exceptions import GMTCLibError, GMTInvalidInput from pygmt.helpers import GMTTempFile @@ -18,7 +19,7 @@ def fixture_dtypes(): """ List of supported numpy dtypes. """ - return "int8 int16 int32 int64 uint8 uint16 uint32 uint64 float32 float64".split() + return [dtype for dtype in DTYPES_NUMERIC if dtype != np.timedelta64] @pytest.mark.benchmark diff --git a/pygmt/tests/test_clib_virtualfile_from_matrix.py b/pygmt/tests/test_clib_virtualfile_from_matrix.py index 6d1a42fa14b..6d4c855ac05 100644 --- a/pygmt/tests/test_clib_virtualfile_from_matrix.py +++ b/pygmt/tests/test_clib_virtualfile_from_matrix.py @@ -5,6 +5,7 @@ import numpy as np import pytest from pygmt import clib +from pygmt.clib.session import DTYPES_NUMERIC from pygmt.helpers import GMTTempFile @@ -13,7 +14,7 @@ def fixture_dtypes(): """ List of supported numpy dtypes. """ - return "int8 int16 int32 int64 uint8 uint16 uint32 uint64 float32 float64".split() + return [dtype for dtype in DTYPES_NUMERIC if dtype != np.timedelta64] @pytest.mark.benchmark diff --git a/pygmt/tests/test_clib_virtualfile_from_vectors.py b/pygmt/tests/test_clib_virtualfile_from_vectors.py index 18cb4053f37..041bc7a803c 100644 --- a/pygmt/tests/test_clib_virtualfile_from_vectors.py +++ b/pygmt/tests/test_clib_virtualfile_from_vectors.py @@ -8,6 +8,7 @@ import pandas as pd import pytest from pygmt import clib +from pygmt.clib.session import DTYPES_NUMERIC from pygmt.exceptions import GMTInvalidInput from pygmt.helpers import GMTTempFile @@ -17,7 +18,7 @@ def fixture_dtypes(): """ List of supported numpy dtypes. """ - return "int8 int16 int32 int64 uint8 uint16 uint32 uint64 float32 float64".split() + return [dtype for dtype in DTYPES_NUMERIC if dtype != np.timedelta64] @pytest.fixture(scope="module", name="dtypes_pandas") @@ -26,10 +27,8 @@ def fixture_dtypes_pandas(dtypes): List of supported pandas dtypes. """ dtypes_pandas = dtypes.copy() - if find_spec("pyarrow") is not None: - dtypes_pandas.extend([f"{dtype}[pyarrow]" for dtype in dtypes_pandas]) - + dtypes_pandas.extend([f"{np.dtype(dtype).name}[pyarrow]" for dtype in dtypes]) return tuple(dtypes_pandas) diff --git a/pygmt/tests/test_clib_virtualfiles.py b/pygmt/tests/test_clib_virtualfiles.py index a05790894d0..a45a662de71 100644 --- a/pygmt/tests/test_clib_virtualfiles.py +++ b/pygmt/tests/test_clib_virtualfiles.py @@ -2,12 +2,12 @@ Test the Session.open_virtualfile method. """ -from importlib.util import find_spec from pathlib import Path import numpy as np import pytest from pygmt import clib +from pygmt.clib.session import DTYPES_NUMERIC from pygmt.exceptions import GMTCLibError, GMTInvalidInput from pygmt.helpers import GMTTempFile from pygmt.tests.test_clib import mock @@ -28,20 +28,7 @@ def fixture_dtypes(): """ List of supported numpy dtypes. """ - return "int8 int16 int32 int64 uint8 uint16 uint32 uint64 float32 float64".split() - - -@pytest.fixture(scope="module", name="dtypes_pandas") -def fixture_dtypes_pandas(dtypes): - """ - List of supported pandas dtypes. - """ - dtypes_pandas = dtypes.copy() - - if find_spec("pyarrow") is not None: - dtypes_pandas.extend([f"{dtype}[pyarrow]" for dtype in dtypes_pandas]) - - return tuple(dtypes_pandas) + return [dtype for dtype in DTYPES_NUMERIC if dtype != np.timedelta64] @pytest.mark.benchmark diff --git a/pygmt/tests/test_grdimage_image.py b/pygmt/tests/test_grdimage_image.py index e2ec8980d18..5314c3882a2 100644 --- a/pygmt/tests/test_grdimage_image.py +++ b/pygmt/tests/test_grdimage_image.py @@ -2,8 +2,10 @@ Test Figure.grdimage on 3-band RGB images. """ +import numpy as np import pytest from pygmt import Figure +from pygmt.clib.session import DTYPES_NUMERIC from pygmt.datasets import load_blue_marble rioxarray = pytest.importorskip("rioxarray") @@ -43,7 +45,7 @@ def test_grdimage_image_dataarray(xr_image): @pytest.mark.parametrize( "dtype", - ["int8", "uint16", "int16", "uint32", "int32", "float32", "float64"], + [dtype for dtype in DTYPES_NUMERIC if dtype not in {np.uint8, np.timedelta64}], ) def test_grdimage_image_dataarray_unsupported_dtype(dtype, xr_image): """