diff --git a/examples/text_labels_and_annotations/dfrac_demo.py b/examples/text_labels_and_annotations/dfrac_demo.py new file mode 100644 index 000000000000..4ffd7767c5b0 --- /dev/null +++ b/examples/text_labels_and_annotations/dfrac_demo.py @@ -0,0 +1,28 @@ +r""" +========================================= +The difference between \\dfrac and \\frac +========================================= + +In this example, the differences between the \\dfrac and \\frac TeX macros are +illustrated; in particular, the difference between display style and text style +fractions when using Mathtex. + +.. versionadded:: 2.1 + +.. note:: + To use \\dfrac with the LaTeX engine (text.usetex : True), you need to + import the amsmath package with the text.latex.preamble rc, which is + an unsupported feature; therefore, it is probably a better idea to just + use the \\displaystyle option before the \\frac macro to get this behavior + with the LaTeX engine. + +""" + +import matplotlib.pyplot as plt + +fig = plt.figure(figsize=(5.25, 0.75)) +fig.text(0.5, 0.3, r'\dfrac: $\dfrac{a}{b}$', + horizontalalignment='center', verticalalignment='center') +fig.text(0.5, 0.7, r'\frac: $\frac{a}{b}$', + horizontalalignment='center', verticalalignment='center') +plt.show() diff --git a/lib/matplotlib/mathtext.py b/lib/matplotlib/mathtext.py index 70d2c86540b1..1ecb524eddb6 100644 --- a/lib/matplotlib/mathtext.py +++ b/lib/matplotlib/mathtext.py @@ -2216,6 +2216,10 @@ class Parser(object): The grammar is based directly on that in TeX, though it cuts a few corners. """ + + _math_style_dict = dict(displaystyle=0, textstyle=1, + scriptstyle=2, scriptscriptstyle=3) + _binary_operators = set(''' + * - \\pm \\sqcap \\rhd @@ -2301,6 +2305,7 @@ def __init__(self): p.float_literal = Forward() p.font = Forward() p.frac = Forward() + p.dfrac = Forward() p.function = Forward() p.genfrac = Forward() p.group = Forward() @@ -2389,6 +2394,11 @@ def __init__(self): - ((p.required_group + p.required_group) | Error(r"Expected \frac{num}{den}")) ) + p.dfrac <<= Group( + Suppress(Literal(r"\dfrac")) + - ((p.required_group + p.required_group) | Error(r"Expected \dfrac{num}{den}")) + ) + p.stackrel <<= Group( Suppress(Literal(r"\stackrel")) - ((p.required_group + p.required_group) | Error(r"Expected \stackrel{num}{den}")) @@ -2441,6 +2451,7 @@ def __init__(self): | p.function | p.group | p.frac + | p.dfrac | p.stackrel | p.binom | p.genfrac @@ -3035,8 +3046,11 @@ def _genfrac(self, ldelim, rdelim, rule, style, num, den): state.font, state.fontsize, state.dpi) rule = float(rule) - num.shrink() - den.shrink() + + # If style != displaystyle == 0, shrink the num and den + if style != self._math_style_dict['displaystyle']: + num.shrink() + den.shrink() cnum = HCentered([num]) cden = HCentered([den]) width = max(num.width, den.width) @@ -3069,35 +3083,50 @@ def _genfrac(self, ldelim, rdelim, rule, style, num, den): return result def genfrac(self, s, loc, toks): - assert(len(toks)==1) - assert(len(toks[0])==6) + assert(len(toks) == 1) + assert(len(toks[0]) == 6) return self._genfrac(*tuple(toks[0])) def frac(self, s, loc, toks): - assert(len(toks)==1) - assert(len(toks[0])==2) + assert(len(toks) == 1) + assert(len(toks[0]) == 2) + state = self.get_state() + + thickness = state.font_output.get_underline_thickness( + state.font, state.fontsize, state.dpi) + num, den = toks[0] + + return self._genfrac('', '', thickness, + self._math_style_dict['textstyle'], num, den) + + def dfrac(self, s, loc, toks): + assert(len(toks) == 1) + assert(len(toks[0]) == 2) state = self.get_state() thickness = state.font_output.get_underline_thickness( state.font, state.fontsize, state.dpi) num, den = toks[0] - return self._genfrac('', '', thickness, '', num, den) + return self._genfrac('', '', thickness, + self._math_style_dict['displaystyle'], num, den) def stackrel(self, s, loc, toks): - assert(len(toks)==1) - assert(len(toks[0])==2) + assert(len(toks) == 1) + assert(len(toks[0]) == 2) num, den = toks[0] - return self._genfrac('', '', 0.0, '', num, den) + return self._genfrac('', '', 0.0, + self._math_style_dict['textstyle'], num, den) def binom(self, s, loc, toks): - assert(len(toks)==1) - assert(len(toks[0])==2) + assert(len(toks) == 1) + assert(len(toks[0]) == 2) num, den = toks[0] - return self._genfrac('(', ')', 0.0, '', num, den) + return self._genfrac('(', ')', 0.0, + self._math_style_dict['textstyle'], num, den) def sqrt(self, s, loc, toks): #~ print "sqrt", toks diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_82.pdf b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_82.pdf new file mode 100644 index 000000000000..7fcd5d932ab1 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_82.pdf differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_82.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_82.png new file mode 100644 index 000000000000..55c704c48547 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_82.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_82.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_82.svg new file mode 100644 index 000000000000..19f8a85b606a --- /dev/null +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_cm_82.svg @@ -0,0 +1,231 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_82.pdf b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_82.pdf new file mode 100644 index 000000000000..4b1874debd8a Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_82.pdf differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_82.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_82.png new file mode 100644 index 000000000000..80bde0ec5b5c Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_82.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_82.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_82.svg new file mode 100644 index 000000000000..2c4c3a5baf67 --- /dev/null +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavusans_82.svg @@ -0,0 +1,141 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_82.pdf b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_82.pdf new file mode 100644 index 000000000000..6170feca8d38 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_82.pdf differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_82.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_82.png new file mode 100644 index 000000000000..a6aa19c18065 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_82.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_82.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_82.svg new file mode 100644 index 000000000000..c797a241e0f6 --- /dev/null +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_dejavuserif_82.svg @@ -0,0 +1,154 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_82.pdf b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_82.pdf new file mode 100644 index 000000000000..1657aaf5625a Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_82.pdf differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_82.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_82.png new file mode 100644 index 000000000000..0143688609e4 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_82.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_82.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_82.svg new file mode 100644 index 000000000000..e7574f7f0427 --- /dev/null +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stix_82.svg @@ -0,0 +1,177 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_82.pdf b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_82.pdf new file mode 100644 index 000000000000..085487d51e59 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_82.pdf differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_82.png b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_82.png new file mode 100644 index 000000000000..7921480555f3 Binary files /dev/null and b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_82.png differ diff --git a/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_82.svg b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_82.svg new file mode 100644 index 000000000000..5b7bab5501a8 --- /dev/null +++ b/lib/matplotlib/tests/baseline_images/test_mathtext/mathtext_stixsans_82.svg @@ -0,0 +1,149 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/matplotlib/tests/test_mathtext.py b/lib/matplotlib/tests/test_mathtext.py index 544d3ef89201..7ef77ce6a5a7 100644 --- a/lib/matplotlib/tests/test_mathtext.py +++ b/lib/matplotlib/tests/test_mathtext.py @@ -111,6 +111,7 @@ r'$\overline{\omega}^x \frac{1}{2}_0^x$', # github issue #5444 r'$,$ $.$ $1{,}234{, }567{ , }890$ and $1,234,567,890$', # github issue 5799 r'$\left(X\right)_{a}^{b}$', # github issue 7615 + r'$\dfrac{\$100.00}{y}$', # github issue #1888 ] digits = "0123456789" @@ -227,6 +228,8 @@ def test_fontinfo(): (r'$\rightF$', r'Unknown symbol: \rightF'), (r'$\left(\right$', r'Expected a delimiter'), (r'$\left($', r'Expected "\right"'), + (r'$\dfrac$', r'Expected \dfrac{num}{den}'), + (r'$\dfrac{}{}$', r'Expected \dfrac{num}{den}'), ], ids=[ 'hspace without value', @@ -247,6 +250,8 @@ def test_fontinfo(): 'right with invalid delimiter', 'unclosed parentheses with sizing', 'unclosed parentheses without sizing', + 'dfrac without parameters', + 'dfrac with empty parameters', ] ) def test_mathtext_exceptions(math, msg):