Skip to content

Commit

Permalink
BUG: fix default math font in yt plots against matplotlib >= 3.4
Browse files Browse the repository at this point in the history
  • Loading branch information
neutrinoceros committed Sep 18, 2021
1 parent 0623cdf commit e1c0e98
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 88 deletions.
1 change: 0 additions & 1 deletion tests/matplotlibrc
@@ -1,4 +1,3 @@
#### MATPLOTLIBRC FORMAT

backend : Agg
mathtext.fontset : cm
14 changes: 14 additions & 0 deletions yt/visualization/_commons.py
@@ -1,6 +1,9 @@
import os
from typing import Optional

import matplotlib
from packaging.version import Version

from yt.utilities.logger import ytLogger as mylog

from ._mpl_imports import (
Expand All @@ -10,6 +13,17 @@
FigureCanvasSVG,
)

MPL_VERSION = Version(matplotlib.__version__)

DEFAULT_FONT_PROPERTIES = {
"family": "stixgeneral",
"size": 18,
}

if MPL_VERSION >= Version("3.4"):
DEFAULT_FONT_PROPERTIES["math_fontfamily"] = "cm"


AGG_FORMATS = [".png", ".jpg", ".jpeg", ".raw", ".rgba", ".tif", ".tiff"]
SUPPORTED_FORMATS = AGG_FORMATS + [".eps", ".ps", ".pdf", ".svg"]

Expand Down
25 changes: 14 additions & 11 deletions yt/visualization/plot_container.py
@@ -1,13 +1,14 @@
import base64
import builtins
import os
import sys
import textwrap
from collections import defaultdict
from functools import wraps

import matplotlib
import numpy as np
from matplotlib.cm import get_cmap
from matplotlib.font_manager import FontProperties
from more_itertools.more import always_iterable

from yt._maintenance.deprecation import issue_deprecation_warning
Expand All @@ -19,7 +20,7 @@
from yt.utilities.definitions import formatted_length_unit_names
from yt.utilities.exceptions import YTNotInsideNotebook

from ._commons import validate_image_name
from ._commons import DEFAULT_FONT_PROPERTIES, validate_image_name

try:
import cmocean
Expand Down Expand Up @@ -248,19 +249,20 @@ class PlotContainer:
_units_config: dict

def __init__(self, data_source, figure_size, fontsize):
from matplotlib.font_manager import FontProperties

self.data_source = data_source
self.ds = data_source.ds
self.ts = self._initialize_dataset(self.ds)
if is_sequence(figure_size):
self.figure_size = float(figure_size[0]), float(figure_size[1])
else:
self.figure_size = float(figure_size)
font_path = os.path.join(
matplotlib.get_data_path(), "fonts", "ttf", "STIXGeneral.ttf"
)
self._font_properties = FontProperties(size=fontsize, fname=font_path)

if sys.version_info >= (3, 9):
font_dict = DEFAULT_FONT_PROPERTIES | {"size": fontsize}
else:
font_dict = {**DEFAULT_FONT_PROPERTIES, "size": fontsize}

self._font_properties = FontProperties(**font_dict)
self._font_color = None
self._xlabel = None
self._ylabel = None
Expand Down Expand Up @@ -508,16 +510,17 @@ def set_font(self, font_dict=None):
... )
"""
from matplotlib.font_manager import FontProperties

if font_dict is None:
font_dict = {}
if "color" in font_dict:
self._font_color = font_dict.pop("color")
# Set default values if the user does not explicitly set them.
# this prevents reverting to the matplotlib defaults.
font_dict.setdefault("family", "stixgeneral")
font_dict.setdefault("size", 18)
if sys.version_info >= (3, 9):
font_dict = DEFAULT_FONT_PROPERTIES | font_dict
else:
font_dict = {**DEFAULT_FONT_PROPERTIES, **font_dict}
self._font_properties = FontProperties(**font_dict)
return self

Expand Down
82 changes: 6 additions & 76 deletions yt/visualization/profile_plotter.py
Expand Up @@ -6,6 +6,7 @@

import matplotlib
import numpy as np
from matplotlib.font_manager import FontProperties
from more_itertools.more import always_iterable, unzip
from packaging.version import parse as parse_version

Expand All @@ -17,10 +18,11 @@
from yt.utilities.logger import ytLogger as mylog

from ..data_objects.selection_objects.data_selection_objects import YTSelectionContainer
from ._commons import validate_image_name
from ._commons import DEFAULT_FONT_PROPERTIES, validate_image_name
from .base_plot_types import ImagePlotMPL, PlotMPL
from .plot_container import (
ImagePlotContainer,
PlotContainer,
get_log_minorticks,
invalidate_plot,
linear_transform,
Expand Down Expand Up @@ -113,7 +115,7 @@ def data_object_or_all_data(data_source):
return data_source


class ProfilePlot:
class ProfilePlot(PlotContainer):
r"""
Create a 1d profile plot from a data source or from a list
of profile objects.
Expand Down Expand Up @@ -374,6 +376,7 @@ def _setup_plots(self):
fontproperties=self._font_properties,
**self._text_kwargs[f],
)
self._set_font_properties()

for i, profile in enumerate(self.profiles):
for field, field_data in profile.items():
Expand Down Expand Up @@ -415,9 +418,7 @@ def _initialize_instance(cls, obj, profiles, labels, plot_specs, y_log):
obj._text_ypos = {}
obj._text_kwargs = {}

from matplotlib.font_manager import FontProperties

obj._font_properties = FontProperties(family="stixgeneral", size=18)
obj._font_properties = FontProperties(**DEFAULT_FONT_PROPERTIES)
obj._font_color = None
obj.profiles = list(always_iterable(profiles))
obj.x_log = None
Expand Down Expand Up @@ -1336,77 +1337,6 @@ def save(self, name=None, suffix=".png", mpl_kwargs=None):
self.plots[f].save(name, mpl_kwargs)
return names

@invalidate_plot
def set_font(self, font_dict=None):
"""
Set the font and font properties.
Parameters
----------
font_dict : dict
A dict of keyword parameters to be passed to
:class:`matplotlib.font_manager.FontProperties`.
Possible keys include:
* family - The font family. Can be serif, sans-serif, cursive,
'fantasy', or 'monospace'.
* style - The font style. Either normal, italic or oblique.
* color - A valid color string like 'r', 'g', 'red', 'cobalt',
and 'orange'.
* variant - Either normal or small-caps.
* size - Either a relative value of xx-small, x-small, small,
medium, large, x-large, xx-large or an absolute font size, e.g. 12
* stretch - A numeric value in the range 0-1000 or one of
ultra-condensed, extra-condensed, condensed, semi-condensed,
normal, semi-expanded, expanded, extra-expanded or ultra-expanded
* weight - A numeric value in the range 0-1000 or one of ultralight,
light, normal, regular, book, medium, roman, semibold, demibold,
demi, bold, heavy, extra bold, or black
See the matplotlib font manager API documentation for more details.
https://matplotlib.org/stable/api/font_manager_api.html
Notes
-----
Mathtext axis labels will only obey the `size` and `color` keyword.
Examples
--------
This sets the font to be 24-pt, blue, sans-serif, italic, and
bold-face.
>>> prof = ProfilePlot(
... ds.all_data(), ("gas", "density"), ("gas", "temperature")
... )
>>> slc.set_font(
... {
... "family": "sans-serif",
... "style": "italic",
... "weight": "bold",
... "size": 24,
... "color": "blue",
... }
... )
"""
from matplotlib.font_manager import FontProperties

if font_dict is None:
font_dict = {}
if "color" in font_dict:
self._font_color = font_dict.pop("color")
# Set default values if the user does not explicitly set them.
# this prevents reverting to the matplotlib defaults.
font_dict.setdefault("family", "stixgeneral")
font_dict.setdefault("size", 18)
self._font_properties = FontProperties(**font_dict)
return self

@invalidate_plot
def set_title(self, field, title):
"""Set a title for the plot.
Expand Down

0 comments on commit e1c0e98

Please sign in to comment.