GenericMappingTools / pygmt

A Python interface for the Generic Mapping Tools.
https://www.pygmt.org
BSD 3-Clause "New" or "Revised" License
758 stars 220 forks source link

How to set font size on scale bar? #3230

Closed Dani-Lindsay closed 6 months ago

Dani-Lindsay commented 6 months ago

Hi all,

I was having trouble with using transparency and solved this by just reinstalling pygmt in a new conda environment but now the font on my scale bars has gone strange... What config parameter controls the font size on the color bars? I tried to set all the different font configs to override this but didn't worked.

Screenshot 2024-05-06 at 10 44 25 AM

Old environment...

(pygmt) daniellelindsay@ras-17-156 ~ % ipython 
Python 3.10.14 | packaged by conda-forge | (main, Mar 20 2024, 12:53:34) [Clang 16.0.6 ]
Type 'copyright', 'credits' or 'license' for more information
IPython 7.33.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pygmt
   ...: pygmt.show_versions()
PyGMT information:
  version: v0.11.0
System information:
  python: 3.10.14 | packaged by conda-forge | (main, Mar 20 2024, 12:53:34) [Clang 16.0.6 ]
  executable: /Users/daniellelindsay/miniconda3/envs/pygmt/bin/python
  machine: macOS-14.3.1-x86_64-i386-64bit
Dependency information:
  numpy: 1.26.4
  pandas: 2.2.2
  xarray: 2024.3.0
  netCDF4: 1.6.2
  packaging: 24.0
  contextily: 1.3.0
  geopandas: None
  ipython: None
  rioxarray: 0.15.0
  ghostscript: 10.03.0
GMT library information:
  binary version: 6.4.0
  cores: 8
  grid layout: rows
  image layout: 
  library path: /Users/daniellelindsay/miniconda3/envs/pygmt/lib/libgmt.dylib
  padding: 2
  plugin dir: /Users/daniellelindsay/miniconda3/envs/pygmt/lib/gmt/plugins
  share dir: /Users/daniellelindsay/miniconda3/envs/pygmt/share/gmt
  version: 6.4.0

New environment...

(pygmt24) daniellelindsay@ras-17-156 ~ % ipython 
Python 3.12.3 | packaged by conda-forge | (main, Apr 15 2024, 18:50:49) [Clang 16.0.6 ]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.22.2 -- An enhanced Interactive Python. Type '?' for help.

In [1]: import pygmt
   ...: pygmt.show_versions()
PyGMT information:
  version: v0.11.0
System information:
  python: 3.12.3 | packaged by conda-forge | (main, Apr 15 2024, 18:50:49) [Clang 16.0.6 ]
  executable: /Users/daniellelindsay/miniconda3/envs/pygmt24/bin/python3.12
  machine: macOS-14.3.1-x86_64-i386-64bit
Dependency information:
  numpy: 1.26.4
  pandas: 2.2.2
  xarray: 2024.3.0
  netCDF4: 1.6.5
  packaging: 24.0
  contextily: None
  geopandas: None
  ipython: None
  rioxarray: None
  ghostscript: 10.03.0
GMT library information:
  binary version: 6.5.0
  cores: 8
  grid layout: rows
  image layout: 
  library path: /Users/daniellelindsay/miniconda3/envs/pygmt24/lib/libgmt.dylib
  padding: 2
  plugin dir: /Users/daniellelindsay/miniconda3/envs/pygmt24/lib/gmt/plugins
  share dir: /Users/daniellelindsay/miniconda3/envs/pygmt24/share/gmt
  version: 6.5.0

Code to make these plots

grid = pygmt.datasets.load_earth_relief(resolution="15s", region=region)
dgrid = pygmt.grdgradient(grid=grid, radiance=[270, 30], region=region)

fig = pygmt.Figure()
pygmt.config(FONT=10, FONT_TITLE=10, PS_MEDIA="A4", FORMAT_GEO_MAP="ddd", MAP_FRAME_TYPE="plain")

with fig.subplot(nrows=1, ncols=2, figsize=("15c", "11.1c"), margins=["0.5c", "0.5c"], frame=["WSrt"], autolabel="a)", sharex="l"):

    pygmt.makecpt(cmap="gray", series=[-1.5, 0.3, 0.01])
    fig.basemap(region=region, projection=fig_size, frame=["WSrt", "xa", "ya"], panel=True)
    fig.grdimage(grid=dgrid, region=region, projection=fig_size, cmap=True, frame=["WSrt", "xa", "ya"], transparency=60)
    fig.coast(region=region, projection=fig_size, shorelines=True, borders="2")

    pygmt.makecpt(cmap="vik", series=[-30, 30])
    fig.grdimage(grid=grd_LUTZ_east, region=region, projection=fig_size, nan_transparent=True, cmap=True)
    fig.colorbar(position="jBL+o0.4c/0.4c+w4c/0.4c", frame=["xa+lVelocity", "y+lmm/yr"], projection=fig_size,)

    fig.text(region=region, projection=fig_size, text="East", position="TR", offset="-0.2c/-0.2c", font="12p,Helvetica-Bold,black", pen="black", fill="white")

    fig.basemap(region=region, projection=fig_size, frame=["wSrt", "xa", "ya"], panel=True)

    pygmt.makecpt(cmap="gray", series=[-1.5, 0.3, 0.01])
    fig.grdimage(grid=dgrid, region=region, projection=fig_size, cmap=True, frame=["wSrt", "xa", "ya"], transparency=60)
    fig.coast(region=region, projection=fig_size, shorelines=True, borders="2")
    pygmt.makecpt(cmap="vik", series=[-30, 30])
    fig.grdimage(grid=grd_LUTZ_up, region=region, projection=fig_size, nan_transparent=True, cmap=True)
    fig.colorbar(position="jBL+o0.4c/0.4c+w4c/0.4c", frame=["xa+lVelocity", "y+lmm/yr"], projection=fig_size)
    fig.text(region=region, projection=fig_size, text="Up", position="TR", offset="-0.2c/-0.2c", font="12p,Helvetica-Bold,black", pen="black", fill="white")

fname = fig_dir + "LUTZ_up_hz_pygmt24_env.png"
fig.savefig(fname, transparent=False, crop=True, anti_alias=True, show=False)
fig.show()
welcome[bot] commented 6 months ago

👋 Thanks for opening your first issue here! Please make sure you filled out the template with as much detail as possible. You might also want to take a look at our contributing guidelines and code of conduct.

yvonnefroehlich commented 6 months ago

Hello @Dani-Lindsay,

The issue with the transparency is related to ghostscript. It is known that there are issues with transparency in GMT 6.4.0 when using gostscript 10.03.0. These issues are fixed in GMT 6.5.0.

The different behaviour of the font size is related to the change from GMT 6.4.0 to 6.5.0. For details please see the GMT documentation at https://docs.generic-mapping-tools.org/dev/colorbar.html#description.

Changing the font size locally can help here:

import pygmt

size = 5

# (I)
fig = pygmt.Figure()
fig.basemap(region=[-size, size, -size, size], projection=f"X{size}c", frame=1)
fig.colorbar(cmap="batlow", position="jMC", frame=["x+lquantity", "y+lunit"])
fig.show()

# (II)
fig = pygmt.Figure()
fig.basemap(region=[-size, size, -size, size], projection=f"X{size}c", frame=1)
# local changes of GMT defaults via context manager
with pygmt.config(
    FONT_ANNOT_PRIMARY="17p,blue", 
    FONT_ANNOT_SECONDARY="15p,darkgreen",
    FONT_LABEL="20p,orange",
):
    fig.colorbar(cmap="batlow", position="jMC", frame=["x+lquantity", "y+lunit"])
fig.show()
(I) (II)
colorbar_font_650 colorbar_font_650_locally

duplicate to

Dani-Lindsay commented 6 months ago

Sorry, just re-read the link above. So this is a feature of "modern mode" and the fonts are automatically scaled and overwrite the pygmt.config(). Makes sense! Thanks. Here my original message still...

...

Thanks for your quick response @yvonnefroehlich ! This does look like the issue in #3041 linked above.

I just played around with this a little bit. Code below for this figure. As you can see using pygmt.config() at the beginning does set font for the boarder but not for the color scale [left]. The local setting does work that you did suggestion above [right]. It's odd that the scale bar font specify locally at 20p is pretty much the same size as the text at 10p in the centre of the figure. Are you able to recreate this error?

font_size_test

fig = pygmt.Figure()
pygmt.config(FONT=10, FONT_TITLE=10, PS_MEDIA="A4", FORMAT_GEO_MAP="ddd", MAP_FRAME_TYPE="plain", FONT_ANNOT_PRIMARY="10p,blue", 
             FONT_ANNOT_SECONDARY="10p,darkgreen", FONT_LABEL="10p,orange")

with fig.subplot(nrows=1, ncols=2, figsize=("15c", "11.1c"), margins=["0.5c", "0.5c"], frame=["WSrt"], autolabel="a)", sharex="l"):

    pygmt.makecpt(cmap="gray", series=[-1.5, 0.3, 0.01])
    fig.basemap(region=region, projection=fig_size, frame=["WSrt", "xa", "ya"], panel=True)
    #fig.grdimage(grid=dgrid, region=region, projection=fig_size, cmap=True, frame=["WSrt", "xa", "ya"], transparency=60)
    fig.coast(region=region, projection=fig_size, shorelines=True, borders="2", water ="white")
    pygmt.makecpt(cmap="vik", series=[-30, 30])
    #fig.grdimage(grid=grd_LUTZ_east, region=region, projection=fig_size, nan_transparent=True, cmap=True)
    fig.colorbar(position="jBL+o0.4c/0.4c+w4c/0.4c", frame=["xa+lconfig 10p", "y+lmm/yr"], projection=fig_size,)
    fig.text(region=region, projection=fig_size, text="East", position="TR", offset="-0.2c/-0.2c", font="12p,Helvetica-Bold,black", pen="black", fill="white")
    fig.text(region=region, projection=fig_size, text="Text 10p", position="CM", offset="-0.2c/-0.2c", font="10p,Helvetica-Bold,black", pen="black", fill="white")

    fig.basemap(region=region, projection=fig_size, frame=["wSrt", "xa", "ya"], panel=True)    
    pygmt.makecpt(cmap="gray", series=[-1.5, 0.3, 0.01])
    #fig.grdimage(grid=dgrid, region=region, projection=fig_size, cmap=True, frame=["wSrt", "xa", "ya"], transparency=60)
    fig.coast(region=region, projection=fig_size, shorelines=True, borders="2", water ="white")
    pygmt.makecpt(cmap="vik", series=[-30, 30])
    #fig.grdimage(grid=grd_LUTZ_up, region=region, projection=fig_size, nan_transparent=True, cmap=True)
    with pygmt.config(
            FONT_ANNOT_PRIMARY="17p,red", 
        FONT_ANNOT_SECONDARY="15p,purple",
        FONT_LABEL="20p,purple",
    ):
        fig.colorbar(position="jBL+o0.4c/0.4c+w4c/0.4c", frame=["xa+l20p local font_label", "y+lmm/yr"], projection=fig_size)
    fig.text(region=region, projection=fig_size, text="Up", position="TR", offset="-0.2c/-0.2c", font="12p,Helvetica-Bold,black", pen="black", fill="white")
    fig.text(region=region, projection=fig_size, text="Text 10p", position="CM", offset="-0.2c/-0.2c", font="10p,Helvetica-Bold,black", pen="black", fill="white")

fname = fig_dir + "font_size_test.png"
fig.savefig(fname, transparent=False, crop=True, anti_alias=True, show=False)
fig.show()
yvonnefroehlich commented 6 months ago

This is due to the change in GMT 6.5.0: The font size of the colorbar is scaled relatively to the length of the colorbar. This seems to be the case even a fixed font size is given via adjusting the GMT defaults locally:

import pygmt

size = 5

for size_cb in [
    "",   # (III) Use default length of the colorbar
    "+w1c",  # (IV) # Make the colorbar shorter than the default
    "+w5c",  # (V) # Make the colorbar longer than the default
]:

    fig = pygmt.Figure()
    fig.basemap(region=[-size, size, -size, size], projection=f"X{size}c", frame=1)
    fig.text(position="MC", text="text in 15p", font="15p")
    # local changes of GMT defaults via context manager
    with pygmt.config(
        FONT_ANNOT_PRIMARY="15p,blue", 
        FONT_ANNOT_SECONDARY="15p,darkgreen",
        FONT_LABEL="15p,orange",
    ):
        fig.colorbar(
            cmap="batlow",
            position=f"jMR{size_cb}",
            frame=["x+lquantity", "y+lunit"],
        )
    fig.show()
(III) default length (IV) smaller length (V) longer length
colorbar_font_650_locally_width_default colorbar_font_650_locally_width_smaler1c colorbar_font_650_locally_width_larger5c