Skip to content

Commit

Permalink
Merge pull request #3597 from meeseeksmachine/auto-backport-of-pr-352…
Browse files Browse the repository at this point in the history
…0-on-yt-4.0.x

Backport PR #3520 on branch yt-4.0.x (BUG: fix default math font in yt plots against matplotlib >= 3.4)
  • Loading branch information
neutrinoceros committed Oct 16, 2021
2 parents 7208a68 + 2c44cb0 commit ea7a964
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 91 deletions.
2 changes: 1 addition & 1 deletion answer-store
1 change: 0 additions & 1 deletion tests/matplotlibrc
@@ -1,4 +1,3 @@
#### MATPLOTLIBRC FORMAT

backend : Agg
mathtext.fontset : cm
4 changes: 2 additions & 2 deletions tests/tests.yaml
Expand Up @@ -92,7 +92,7 @@ answer_tests:
- yt/frontends/owls/tests/test_outputs.py:test_snapshot_033
- yt/frontends/owls/tests/test_outputs.py:test_OWLS_particlefilter

local_pw_037: # PR 3373
local_pw_038: # PR 3520
- yt/visualization/tests/test_plotwindow.py:test_attributes
- yt/visualization/tests/test_particle_plot.py:test_particle_projection_answers
- yt/visualization/tests/test_particle_plot.py:test_particle_projection_filter
Expand Down Expand Up @@ -167,7 +167,7 @@ answer_tests:
local_axialpix_007:
- yt/geometry/coordinates/tests/test_axial_pixelization.py:test_axial_pixelization

local_cylindrical_background_008: # PR 3536
local_cylindrical_background_010: # PR 3520
- yt/geometry/coordinates/tests/test_cylindrical_coordinates.py:test_noise_plots

local_spherical_background_002: # PR 3533 + 3520
Expand Down
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 # noqa
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 ea7a964

Please sign in to comment.