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

Allow use of matplotlib relative font sizes #617

Closed MarkWieczorek closed 7 months ago

MarkWieczorek commented 4 years ago

Matplotlib defines a set of relative font sizes, such as "medium" and "large". Unfortunately, matplotlib mixes absolute and relative font sizes in the rcParams dictionary. When using pygmt, I often take the font sizes from my existing rcParams dictionary, and then pass them to pygmt.config to customize my plots like this:

pygmt.config(FONT_TITLE=mpl.rcParams['axes.titlesize'])

If the font size it somthing like "medium", pygmt.config doesn't know what to do and generates a warning.

One way around this would be for pygmt.config to convert the relative font sizes (str) to absolute font sizes (float). I found this method that does just this:

In [1]: mpl.font_manager.FontProperties(size='large').get_size_in_points()
Out[1]: 12.0

Another way would be to use this predifined dictionary:

In [2]: mpl.font_manager.font_scalings
Out[2]:
{'xx-small': 0.579,
 'x-small': 0.694,
 'small': 0.833,
 'medium': 1.0,
 'large': 1.2,
 'x-large': 1.44,
 'xx-large': 1.728,
 'larger': 1.2,
 'smaller': 0.833,
 None: 1.0}

The easiest thing to do would be to test if the font size is a string, and if True, use one of the above methods to convert it to points.

weiji14 commented 4 years ago

One way around this would be for pygmt.config to convert the relative font sizes (str) to absolute font sizes (float). I found this method that does just this:

In [1]: mpl.font_manager.FontProperties(size='large').get_size_in_points()
Out[1]: 12.0

Interesting idea. I'd like to hear from the rest of the team to see if this is within scope for pygmt, or best classified as an advanced feature. Yes we want pygmt to be easy to use, but @leouieda also mentioned before at https://github.com/GenericMappingTools/pygmt/pull/427#issuecomment-646983555 that we should avoid repeating the mistakes of matplotlib (namely having too many ways to do one thing, which goes agaist the Zen of Python - "There should be one-- and preferably only one --obvious way to do it.").

seisman commented 4 years ago

The easiest thing to do would be to test if the font size is a string, and if True, use one of the above methods to convert it to points.

It's more complicated, as GMT settings like FONT_TITLE set font type, size and color.

seisman commented 7 months ago

In the GMT world, a font contains three attributes, size, fonttype and fill. An example of a valid font is 12p,Times-Roman,red.

To support relative font sizes like medium,Times-Roman,red, we have to parse every font-like arguments, and replace the relative font sizes with absolute values, which means a lot of coding work and is not the goal of PyGMT. I don't think we will implement it in PyGMT so I'm closing the issue.

Actually, this is an interesting idea that may be implemented in GMT instead. For reference, GMT's pen attribute has syntax like 2p,red,-, in which the pen width can be some special pen names like thin/thick/fat. I guess it's not that hard to have similar special/relative font sizes in GMT.

Please open a feature request on the GMT repository if you're still interested.