Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add tutorial for pygmt.config #482

Merged
merged 13 commits into from
Oct 29, 2020
1 change: 1 addition & 0 deletions doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
projections/index.rst
tutorials/coastlines.rst
tutorials/plot.rst
tutorials/gmt-config.rst
hemmelig marked this conversation as resolved.
Show resolved Hide resolved

.. toctree::
:maxdepth: 2
Expand Down
68 changes: 68 additions & 0 deletions examples/tutorials/gmt-config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
"""
Configuring PyGMT defaults
==========================

Default GMT parameters can be set globally or locally using :class:`pygmt.config`
"""

import pygmt

########################################################################################
# Configuring default GMT parameters
# ----------------------------------
#
# The user can override default parameters either temporarily (locally) or permanently
# (globally) using :meth:`pygmt.config`. The full list of default parameters that can be
# changed can be at :gmt-docs:`gmt.conf.html`.
#
# We demonstrate the usage of :meth:`pygmt.config` by configuring a map plot.

# Start with a basic figure
fig = pygmt.Figure()
fig.basemap(region=[115, 119.5, 4, 7.5], projection="M10c", frame=True)
fig.coast(land="black", water="skyblue")

fig.show()

########################################################################################
# Globally overriding defaults
# ----------------------------
#
# The `MAP_FRAME_TYPE` parameter specifies the style of map frame to use, of which there
hemmelig marked this conversation as resolved.
Show resolved Hide resolved
# are 3 options: `fancy` (default, seen above), `plain`, and `inside`.
hemmelig marked this conversation as resolved.
Show resolved Hide resolved
#
# The `FORMAT_GEO_MAP` parameter controls the format of geographical tick annotations.
hemmelig marked this conversation as resolved.
Show resolved Hide resolved
# The default uses degrees and minutes. Here we specify the ticks to be a decimal number
# of degrees.

pygmt.config(MAP_FRAME_TYPE="plain")
pygmt.config(FORMAT_GEO_MAP="ddd.xx")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In GMT 6.1.0, each session can have a global gmt.conf file, and each figure can also have its own gmt.conf (see https://docs.generic-mapping-tools.org/6.1/cookbook/features.html#gmt-modern-mode-hierarchical-levels).

Now these two lines no longer works as we expected. They actually change the defaults of the figure above. To change the defaults of the current figure, we need to move these two lines after fig=pygmt.Figure().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So hierarchically one must do something like:

# Set global (session) configuration

fig = pygmt.Figure()  # This will change the current 'level' from session to figure
# Set figure configuration

etc

That makes sense, I'll fix this up (and finish the two PRs I've opened!)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How would one trigger the further levels mentioned in the GMT 6.1.0 documentation (subplot, panel, inset)?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, subplot and inset are not implemented in PyGMT yet, but see #412 and #427.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just opened up an issue for inset at #663, we can discuss over there. The subplot implementation at #427 is also ready for review 😄

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just read it! I'll have a look at it, thanks.


fig = pygmt.Figure()
fig.basemap(region=[115, 119.5, 4, 7.5], projection="M10c", frame=True)
fig.coast(land="black", water="skyblue")

fig.show()

########################################################################################
# Locally overriding defaults
# ---------------------------
#
# It is also possible to temporarily override the default parameters, which is a very
# useful for limiting the scope of changes to a particular plot. :class:`pygmt.config` is
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As explained above, no need to use the with statement to limit the scope of changes to a single figure, but it's still useful if we want to limit the changes to one or a few calls.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still like the syntax of using a context manager. For me, it's far more intuitive/easy to see the scope of the changes being made than tracking the level based on Figure calls.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it works the same as the figure level configurations, just needs one more indentation. I'm OK with the example, but the main idea of the context manager is to mimic the command line parameter gmt basemap --PARAMETER=value, which only affect one single command. So perhaps we can keep this example, and add one more example.

# implemented as a context manager, which handles the setup and teardown of a GMT
# session. Python users are likely familiar with the `with open(...) as file:` snippet,
# which returns a `file` context manager. An application of `pygmt.config` as a context
# manager is shown below:

# This will have a fancy frame
with pygmt.config(MAP_FRAME_TYPE="fancy"):
fig = pygmt.Figure()
fig.basemap(region=[115, 119.5, 4, 7.5], projection="M10c", frame=True)
fig.coast(land="black", water="skyblue")

# This figure retains the globally set plain frame
fig.basemap(region=[115, 119.5, 4, 7.5], projection="M10c", Y="-10c", frame=True)
fig.coast(land="black", water="skyblue")

fig.show()