PyGMT v0.18.0 released

PyGMT v0.18.0 released

The PyGMT team is starting into 2026 with announcing PyGMT release v0.18.0 :fireworks::sparkler:! This minor release features a Pythonic Position class for enhanced GMT embellishment placement :tada:.

Here are the highlights :tada::

  • :tada: Eighteenth minor release of PyGMT :tada:
  • Enhanced GMT embellishment (e.g., scale bar, GMT logo, image) placement and styling with a Pythonic Position class and additional controlling parameters
  • Five new or updated gallery examples (#4231, #4229, #4228, #4265, #4214)

Nice enhancements :sparkles::

  • AliasSystem: Migrate the registration parameter to the new alias system and support descriptive arguments (#4182)
  • pygmt.grdfilter: Let the parameter nans support descriptive arguments (#4310)
  • Figure.colorbar: Add position/length/width and more parameters to specify colorbar position and properties (#4048)
  • Figure.grdview: Improve parameters plane/facade_fill/facade_pen to set the plane and facade (#4235)
  • Figure.histogram: Split parameter bar_width into bar_width and bar_offset (#4316)
  • Figure.inset: Add parameters position/width/height to specify inset position and dimensions (#4047)
  • Figure.image: Add aliases for -I (invert) and -B (frame) (#4089, #4301)
  • Figure.image: Add parameters position/width/height/dpi/replicate to control image position and properties (#4045)
  • Figure.legend: Add aliases for -S (scale) and -B (frame) (#4254)
  • Figure.legend: Add parameters position/width/height/line_spacing to specify legend position and properties (#4046)
  • Figure.logo: Add parameters position/width/height to specify logo position and dimensions (#4014)
  • Figure.wiggle: Add parameters position/length/label/label_alignment for the scalebar position and properties (#4049)

Read through the changelog for the full list of changes. Installation/upgrade :arrow_up: instructions are at Installing — PyGMT! This version is compatible with GMT 6.5.0 - 6.6.0, and now requires Python 3.12+ :snake:, NumPy 2.0+, pandas 2.2+, and Xarray 2024.5+ following our support policy for GMT and other package dependencies. Go try it online at try-gmt :rocket:.

As usual, please feel free to report any bugs :beetle: with the issue template on GitHub. Your feedback is what helps us to improve :folded_hands:! For example, this issue #3041 and various forum posts like this helped us to realize that GMT’s font size autoscaling for colorbars (introduced in GMT 6.5.0) was potentially confusing, and led us to document a workaround in PR #4126!

:bulb: Additions and updates to Gallery examples

:railway_track: Roadmap to future releases

While the team started to work on a new alias system and continues to enhance functionality, there are still plenty of features and improvements we’d like to add! Check out the good first issue label on GitHub or the list below for things you can help with!

  • PyGMT Logo
    • Thanks to the contributions of @sfrooti, we’re super close to having an official PyGMT logo. If you’d like to provide any feedback during this stage of the design process, please leave your comments in issue #1404 or PR #3849. Stay tuned!
  • Features/enhancements :sparkles:
    • Wrap GMT modules: clip, coupe, earthtide, fitcircle, movie, polar, and sac
    • Implement high-level methods of Figure.plot and Figure.plot3d (#2797): Figure.scatter (#3602), Figure.choropleth (#2798), Figure.errorbar, Figure.stem, Figure.fill_between
    • Implement high-level methods of Figure.basemap or Figure.coast (#2831): Figure.scale_bar (#4015), Figure.directional_rose (#4025), Figure.magnetic_rose (#4051)
  • Documentation improvements :book:
    • Add a beginner :beginner: friendly PyGMT tutorial that is a good roadmap for new GMT/PyGMT users (#770)
    • Add a tutorial explaining the generally accepted input types (#1268)

Please don’t be shy to reach out on GitHub if you’re interested in contributing :smile:! You can have a look at our Contributors Guide to figure out how you can help and get started :rocket:.

:warning: Upcoming deprecations

  • v0.19.0 (Planned for March 2026)
    • pygmt.grdfill: Deprecate parameter no_data to hole (since v0.15.0)
    • pygmt.grdfill: Deprecate parameter mode, use parameters constantfill/gridfill/neighborfill/splinefill instead (since v0.15.0)
    • pygmt.grdclip: Deprecate parameter new to replace (since v0.15.0)
    • utils.sequence_join: Deprecate parameter separator to sep (since v0.17.0)
  • v0.20.0 (Planned for June 2026) (Sorry, but in a long term aproach this will make the names more consistent and intuitive, and they will align with with the PEP 8 style guide)
    • pygmt.grdfill: Deprecate parameters constantfill/gridfill/neighborfill/splinefill to constant_fill/grid_fill/neighbor_fill/spline_fill (since v0.18.0)
    • pygmt.grdlandmask: Deprecate parameters bordervalues/maskvalues to broder_values/mask_values (since v0.18.0)
    • Figure.grdview: Deprecate parameters contourpen/facadepen/meshpen to contour_pen/facade_pen/mesh_pen (since v0.18.0)
    • Figure.grdview: Deprecate parameter drapegrid to drape_grid (since v0.18.0)
    • Figure.histogram: Deprecate parameter barwidth to bar_width (since v0.18.0)
    • Figure.inset: Deprecate parameter margin to clearance (since v0.18.0)
    • Figure.meca: Deprecate parameters compressionfill/extensionfill to compression_fill/extension_fill (since v0.18.0)
    • Figure.meca: Deprecate parameter labelbox to label_box (since v0.18.0)
    • pygmt.select: Deprecate parameter gridmask to mask_grid (since v0.18.0)
    • pygmt.select: Deprecate parameter mask to mask_values (since v0.18.0)
    • pygmt.surface: Deprecate parameter maxradius to max_radius (since v0.18.0)
    • Figure.velo: Deprecate parameters uncertaintyfill to uncertainty_fill (since v0.18.0)
    • Figure.wiggle: Deprecate parameters fillnegative/fillpositive to negative_fill/positive_fill (since v0.18.0)
    • pygmt.x2sys_cross: Deprecate parameter trackvalues to track_values (since v0.18.0)
    • Remove deprecated pygmt.io.load_dataarray (since v0.16.0)
    • Session.virtualfile_in: Remove deprecated parameters required_z/extra_arrays/required_data (since v0.16.0)
  • v0.21.0
    • pygmt.grdsample: Deprecate parameter translate to toggle (since v0.18.0)
  • v1.0.0
    • Short form aliases (e.g. R) will not work if long form aliases (e.g. region) are available (SyntaxWarning raised since PyGMT v0.4.0, see #1316)

The compatibility matrix for GMT, Python, and the required core package dependencies NumPy, pandas, and Xarray is listed at Minimum Supported Versions — PyGMT, so make sure you keep things up to date!

:world_map: Conference presentations/workshops/sprints

What conferences would you like to see GMT/PyGMT at next? IGARSS? FOSS4G? Are you interested in helping to organize a workshop? Let us know in the comments below!

P.S. Share the word on Instagram @genericmappingtools :camera_with_flash: and ResearchGate!

1 Like

you guys (= pygmt developers) have been keeping renaming the long-form pygmt aliases all way long and yet planning to disable short GMT parameters that have been stable literally for years and decades.

It is not reasonable to demand those those who already learned GMT CLI syntax to learn the second set of aliases, esp taking into account this second gets updated with every new version.

I think this idea is bad and I am calling pygmt developers to reconsider.

Isn’t the long-term idea to have a GMT 7 with long-options ?

Making long options available is not equivalent to disabling short options.

1 Like

Thanks for your feedback. We will rediscuss if we will fully disable non-Pythonic short option flags in v1.0.0.

I believe we already have long options. Try the command below. We just need to add it to the documentation.

gmt pscoast --projection=H180/12c --region=d --land=lightbrown --water=lightblue --frame -png ex01

As already mentioned by Dongdong we will have more discussion on fully removing the short option flags in v1.0.0.
Please note that the team is currently working on making the modifiers more Pythonic. This does not only include defining descriptive names, but includes implementing Pythonic parameter class. At the moment we have such classes for Box, Pattern, and Position (API Reference — PyGMT). Furthermore, high-level methods are / will be implemented related to basemap / coast (Higher-level plotting methods for scale bar, map direction rose and magnetic rose? · Issue #2831 · GenericMappingTools/pygmt · GitHub; adding a scale bar and directional and magnetic roses) and plot / plot3d (Higher-level plotting methods for Figure.plot and Figure.plot3d · Issue #2797 · GenericMappingTools/pygmt · GitHub; Figure.hlines, Figure.vlines, scatter, errorbar, choropleth, etc.). Considering these changes and features, there is / will be no direct relation between the PyGMT and GMT codes in the future.

So… instead of having a standalone suite of mapping tools that has a python wrapper, we tend to a python library that leaves GMT behind?

In general, I have not seen long options solving any real issue, instead introducing a couple of new problems out of nowhere: first, new option name needs to be invented (and then it might get changed a few times before it finally settles), new option need to be documented and examples created. Disabling the short options appears to be yet another problem created out of nowhere.

I could easily imagine situations when a long (or just an updated) option could be of real help, like this. There, I stumbled upon -Bs (with regard to axes specs) being ambiguous as it is unclear from the context whether a secondary axis or a single southern axis w/o tick labels is requested. So far I haven’t seen long options directed at solving problem like this one.

I would of course be very happy if proven wrong with the above.

OK, I think this overflowed the PyGMT issue so, and since I was the first to come with the long options and pushed for it in GMT, let me chime in as well.

The situations of the hardcore crypto-classic versus long-options is radically different depending on if one is already a (experienced) GMT user or a beginner. In the first case, the question

  • why learning a new way of doing the same thing if I already know one

makes all the sense … except if you must teach a beginner or just explain what your command means. In the second case though, it is my experience, specially with GMT.jl, that practically no one is available nowdays to learn the cryptic syntax given what they can see in Matplotlib, etc… So for GMT.jl and PyGMT the long options are an absolute must. But that doesn’t mean that thy old syntax should be abandoned. Here I fully agree with Mikhail (have said the same myself for a couple of times).

If it is a good idea or not to advertise it in GMT CLI is still another matter. I still think yes but the documentation issue is a very hard bone to crack.

And regarding de -B’s, very hard too but I think GMT.jl solution is not that bad.

And, about Yvonne’s comment on that. “there is / will be no direct relation between the PyGMT and GMT codes in the future.” I have to disagree. In the end all wrappers have to translate theirs high level syntax (the long options) into the cryto-soupe of letter understandable by GMT, so the possibility to pass a hardcore string with the options should always be open IMO.

If people don’t think anymore GMT is so outstanding it is necessary to learn it by all possible means regardless the option syntax (this is how it was for me), the GMT project may have a much bigger task to solve than just adding long options.

A very good reminder. On the other hand, it is so obvious I didn’t bother to comment.