diff --git a/doc/users/next_whats_new/mathtext_supports_text.rst b/doc/users/next_whats_new/mathtext_supports_text.rst new file mode 100644 index 000000000000..6dbbc31108fc --- /dev/null +++ b/doc/users/next_whats_new/mathtext_supports_text.rst @@ -0,0 +1,12 @@ +``mathtext`` now supports ``\text`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +``\text`` can be used to obtain upright text within an equation. + +.. plot:: + :include-source: true + :alt: Illustration of the newly added \text command, showing that it renders as normal text, including spaces, despite being part of an equation. Also show that a dash is not rendered as a minus when part of a \text command. + +import matplotlib.pyplot as plt +plt.text(0.1, 0.5, r"$a = \sin(\phi) \text{ such that } \phi = \frac{x}{y}$") +plt.text(0.1, 0.3, r"$\text{dashes (-) are retained}$") diff --git a/galleries/users_explain/text/mathtext.py b/galleries/users_explain/text/mathtext.py index 692de482917a..07ab298d0f31 100644 --- a/galleries/users_explain/text/mathtext.py +++ b/galleries/users_explain/text/mathtext.py @@ -272,6 +272,10 @@ that far fewer symbols will be available, but it can be useful to make math expressions blend well with other text in the plot. +For compatibility with popular packages, ``\text{...}`` is available and uses the +``\mathrm{...}`` font, but otherwise retains spaces and renders - as a dash +(not minus). + Custom fonts ~~~~~~~~~~~~ mathtext also provides a way to use custom fonts for math. This method is diff --git a/lib/matplotlib/_mathtext.py b/lib/matplotlib/_mathtext.py index 1c4a37cef9b3..76bad22592e7 100644 --- a/lib/matplotlib/_mathtext.py +++ b/lib/matplotlib/_mathtext.py @@ -1857,6 +1857,7 @@ def csnames(group, names): p.optional_group = Forward() p.sqrt = Forward() p.subsuper = Forward() + p.text = Forward() p.token = Forward() p.underset = Forward() @@ -1907,6 +1908,8 @@ def csnames(group, names): r"\underset", p.optional_group("annotation") + p.optional_group("body")) + p.text <<= cmd(r"\text", QuotedString('{', '\\', endQuoteChar="}")) + p.placeable <<= ( p.accent # Must be before symbol as all accents are symbols | p.symbol # Must be second to catch all named symbols and single @@ -1922,6 +1925,7 @@ def csnames(group, names): | p.underset | p.sqrt | p.overline + | p.text ) p.simple <<= ( @@ -2022,6 +2026,14 @@ def non_math(self, s, loc, toks): float_literal = staticmethod(pyparsing_common.convertToFloat) + def text(self, s, loc, toks): + self.push_state() + state = self.get_state() + state.font = 'rm' + hlist = Hlist([Char(c, state) for c in toks[1]]) + self.pop_state() + return [hlist] + def _make_space(self, percentage): # In TeX, an em (the unit usually used to measure horizontal lengths) # is not the width of the character 'm'; it is the same in different diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext1_dejavusans_04.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext1_dejavusans_04.png new file mode 100644 index 000000000000..a6861a8f1f08 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext1_dejavusans_04.png differ diff --git a/lib/matplotlib/tests/test_mathtext.py b/lib/matplotlib/tests/test_mathtext.py index 2ee3e914d5f6..301906d611b4 100644 --- a/lib/matplotlib/tests/test_mathtext.py +++ b/lib/matplotlib/tests/test_mathtext.py @@ -130,6 +130,8 @@ r'$x \overset{f}{\rightarrow} \overset{f}{x} \underset{xx}{ff} \overset{xx}{ff} \underset{f}{x} \underset{f}{\leftarrow} x$', # github issue #18241 r'$\sum x\quad\sum^nx\quad\sum_nx\quad\sum_n^nx\quad\prod x\quad\prod^nx\quad\prod_nx\quad\prod_n^nx$', # GitHub issue 18085 r'$1.$ $2.$ $19680801.$ $a.$ $b.$ $mpl.$', + r'$\text{text}_{\text{sub}}^{\text{sup}} + \text{\$foo\$} + \frac{\text{num}}{\mathbf{\text{den}}}\text{with space, curly brackets \{\}, and dash -}$', + ] digits = "0123456789"