Skip to content

Feature request: add option to disable mathtext parsing #4938

Closed

Description

@aheays

Could not find a way to do this through current documentation discussion.

Requested feature: Simple way (rcParam?) to disable mathtext processing and instead display raw string.
An alternative might be to print raw string on error rather than fail parsing and entire script.

Use case: Normally process figure strings with latex strings. When prototyping use mathtext for speed, but fails in complex but useful latex cases (e.g., \ce{..} mhchem package). Would be annoying to add extensive try/except code.

Activity

  1. added this to the milestone on Sep 23, 2015
  2. WeatherGod commented on Sep 23, 2015

    @WeatherGod
    Member

    I am amendable to this idea. It probably won't get worked on for a couple
    more months as we sort out the (in-progress) 1.5 release and the
    immediately following style-change-only 2.0 release. Once 2.0 gets
    released, be sure to ping this issue again to remind us.

    On Wed, Sep 23, 2015 at 5:09 AM, Sybren A. Stüvel notifications@github.com
    wrote:

    +1 for another reason: I embed my plots in a LaTeX file, and want to defer
    the text rendering to LaTeX when it's rendering the entire document. That
    way I can use custom LaTeX commands and styles in my figure. Inkscape can
    convert SVG to LaTeX + PDF to support this workflow, and it would be very
    nice if Matplotlib could too. All we need is a toggle to turn it off and
    have raw "$\LaTeX$" in the output.

    —
    Reply to this email directly or view it on GitHub
    #4938 (comment)
    .

  3. sybrenstuvel commented on Sep 24, 2015

    @sybrenstuvel

    +1 for another reason: I embed my plots in a LaTeX file, and want to defer
    the text rendering to LaTeX when it's rendering the entire document. That
    way I can use custom LaTeX commands and styles in my figure. Inkscape can
    convert SVG to LaTeX + PDF to support this workflow, and it would be very
    nice if Matplotlib could too. All we need is a toggle to turn it off and
    have raw "$\LaTeX$" in the output.

    I deleted my post (now quoted above), as it turned out it didn't work as easily as I expected. I got the raw "$\LaTeX$" in the output SVG, but it wasn't picked up by Inkscape to be removed from the SVG and transferred to a .pdf_tex file. Apparently, more has to be done to support my suggested workflow.

  4. tacaswell commented on Sep 24, 2015

    @tacaswell
    Member

    @sybrenstuvel If you are solely targetting latex rendering, have a look at the pgf backend.

  5. modified the milestones: , on Oct 8, 2015
  6. mdboom commented on Nov 8, 2015

    @mdboom
    Member

    Have you tried escaping the dollar signs? i.e. \$\LaTeX\$.

  7. modified the milestones: , on Nov 8, 2015
  8. modified the milestones: , on Oct 3, 2017
  9. 5 remaining items

  10. AJJLagerweij commented on Feb 21, 2021

    @AJJLagerweij

    Just for clarification I made an example:

    import matplotlib.pyplot as plt
    plt.rcParams['svg.fonttype'] = 'none'
    
    plt.figure()
    plt.xlabel(r"Just some text")
    plt.ylabel(r"Local error \$\sum_{d=1}^D \| u_d - \hat{u} \|^2\$")
    plt.savefig('plot.svg')

    When you open this in Inkscape (or Illustrator), will cause your font to be recognized in Inkscape as letters.
    I have this conversion from. svg to .pdf and .pdf_tex automated in my latex permeable.

    \documentclass{article}
    \usepackage{hyperref} % Import and set hyperrefs
    \usepackage{geometry} % Tweakying page layout
    \usepackage{graphicx} % Manage images and colors
    
    % Reading and processing SVG files with correct fonts
    % This can be replaced with using Inkscape and manually
    % exporting the files as .pdf with text as latex. This
    % automated process requires Inkscape to be in your
    % global path, wich is a bit more difficult in windows.
    \newcommand{\executeiffilenewer}[3]{%
    	\ifnum\pdfstrcmp{\pdffilemoddate{#1}}%
    	{\pdffilemoddate{#2}}>0%
    	{\immediate\write18{#3}}\fi%
    }
    \newcommand{\includesvg}[1]{%
    	\executeiffilenewer{#1.svg}{#1.pdf}%
    	{inkscape -z -D --file=#1.svg --export-pdf=#1.pdf --export-latex}%
    	\input{#1.pdf_tex}%
    }
    
    \begin{document}
    \begin{figure}[t!]
    	\centering
    	\def\svgwidth{\textwidth}
    	\includesvg{plot}
    	\caption{An example plot with real latex rendering.}
    \end{figure}
    \end{document}

    This is the resulting folder including the python, latex and image files.
    test.zip

  11. AJJLagerweij commented on Feb 21, 2021

    @AJJLagerweij

    Ahh, thanks for your swift response. I'll have a look at it tomorrow, as it is late already.
    But the alignment is not very important, as the text doesn't scale with your image size the exact alignment is a bit flexible anyway. Generally I correct this in the .svg by hand. (or specify the spacing differently in python). As you mentioned the 'raw string' will be of different length than that it will be in the final .pdf. I had an issue with that ones before. However in general the impact is not to large. As you can see from my example in the previous post even a fairly long string to short rendered math with summations comes out quite nicely. And I did not have to tweak the files in anyway.

    Your proposal where I use a function to convert is actually perfect and this solves all my issues. I'll make an extra example tomorrow to show how this can be use to make a python script that can quickly switch between rendered and non-rendered maths in matplotlib. Afterwards I'll close this request.

    You are right, only the $ requires escaping when you use raw strings (r"$\lambda$" to r"\$\lambdla\$"). In case of other types of strings one will also need to escapes the \ that is "$\lambda$" to "\$\\lambdla\$". This can be useful when we want to combine this with to the string formatting syntax.

  12. jklymak commented on Feb 21, 2021

    @jklymak
    Member

    I still don't follow how that is preferable to

    \documentclass{article}
    \usepackage{hyperref} % Import and set hyperrefs
    \usepackage{geometry} % Tweakying page layout
    \usepackage{graphicx} % Manage images and colors
    \usepackage{tikz,pgf}
    
    \begin{document}
    \begin{figure}
        \begin{center}
            \input{plot.pgf}
        \end{center}
        \caption{An example plot with real latex rendering.}
    \end{figure}
    \end{document}

    which bypasses inkscape altogether:

    testLatex.pdf

  13. AJJLagerweij commented on Feb 22, 2021

    @AJJLagerweij

    I must be honest, I thought that the pgf background worked differently, clearly it is, as you already mentioned a lot closer to what I I need then I thought. In your example however there seems to be a different font in the caption compared to the font in the figure labels. That is exactly what we're trying to avoid, the fonts need to be exactly the same.
    Nevertheless, this might be possible with the pgf backend. I'll try and post an update about this.

    If I manage to fix than the pgf is far superior to the workflow that I'm currently using. I have to say that I'm worried about the latex compile time as it will have to render all the data, and not only the text of the figures. But using draft properly in TeX should allow us to circumvent that.

  14. AJJLagerweij commented on Feb 22, 2021

    @AJJLagerweij

    I've not yet managed to have the font type and size adapt to my latex run automatically with the pgf backend of matplotlib. There is however a workaround that is relatively nice, it is called tikzplotlib. This converts the matplotlib image into a tikzpicture figure that can be processed with the latex package called pgfplots. See the examples here below:

    import matplotlib.pyplot as plt
    from tikzplotlib import save
    
    plt.figure()
    plt.xlabel(r"Just some text")
    plt.ylabel(r"Local error $\sum_{d=1}^D \| u_d - \hat{u} \|^2$")
    
    save("plot.tex",
         axis_height=r"\axheight",
         axis_width=r"\axwidth")
    \documentclass{article}
    \usepackage{geometry}
    \usepackage{pgfplots}
    \pgfplotsset{compat = 1.5}
    
    \newlength\axheight
    \newlength\axwidth
    \newcommand{\plot}[3]{%
    	\setlength\axheigaht{#1}%
    	\setlength\axwidth{#2}%
    	\input{#3}}
    
    
    \begin{document}
    	\begin{figure}
    		\centering
    		\plot{5cm}{5cm}{plot.tex}
    		\caption{An example plot with real latex rendering.}
    	\end{figure}
    
    	\begin{figure}
    	\centering\footnotesize
    	\plot{5cm}{5cm}{plot.tex}
    	\caption{Image of the same size but with different text size.}
    	\end{figure}
    
    	\begin{figure}
    		\centering
    		\plot{6cm}{0.9\textwidth}{plot.tex}
    		\caption{The same image but with different dimensions, The text does not scale with the image.}
    	\end{figure}
    \end{document}

    See the results here: test.zip.
    This is not as flexible and nice as using matplotlib directly, but does do what I expect it to (for simple plots).

  15. aheays commented on Feb 22, 2021

    @aheays
    Author

    This is turning into a great tutorial on pgf and tikzplot etc! But to clarify my particular original problem, I was missing an easy way to display raw mathtext during the development of a plot without escaping everything or raising an error, and then later on switching to usetex with full latex support and perhaps custom \usepackages. For example, a label like:

    plot([1,2,3],label=r'$x(\ce{CH4}) = \SI{1e16}{cm^{-3}}$')
    
  16. AJJLagerweij commented on Feb 22, 2021

    @AJJLagerweij

    Clearly I had a wrong idea regarding your motivation, sorry for that. I think that @anntzer in #4938 (comment) has the solution for you.

    Here is a minimal working example with your string:

    import matplotlib.pyplot as plt
    RAW_MATH = True
    
    def _m(s):
        return s.replace("$", r"\$") if RAW_MATH else s
    
    plt.figure()
    plt.xlabel(_m("Just some text"))
    plt.ylabel(_m("Local error $\sum_{d=1}^D \| u_d - \hat{u} \|^2$"))
    plt.plot([1,2,3],label=_m('$x(\ce{CH4}) = \SI{1e16}{cm^{-3}}$'))
    plt.legend()
    plt.show()
  17. AJJLagerweij commented on Mar 11, 2021

    @AJJLagerweij

    From what I understand, the question was answered and a workaround found. Can it be closed?

    On a separate note, would it be interesting to open another discussion about workflows for matplotlib and latex. Not with the intention to make changes in matplotlib, but with the following goals:

    1. How do people use it (different workflows for probably different reasons),
    2. Drawbacks and benefits to the different approaches,

    This could inform users and help them to improve their reports/publications. Where should such a discussion take place?

  18. jklymak commented on Mar 11, 2021

    @jklymak
    Member

    https://discourse.matplotlib.org is a great place to discuss this.

    I think we will close this, because if I understand correctly, toggling this will lead to bad outcomes with the size of labels being mis-interpreted. So enabling this as a feature will leave us open to a lot of complaints if folks don't understand the drawbacks. The workaround above for those who really need to toggle this seems OK to me. But of course anyone can request a re-open, or make a PR that implements this anyways

  19. spillz commented on Apr 22, 2022

    @spillz

    The workaround is really inconvenient for plotting from third party libs like pandas. I read from databases into dataframes and the column names include liberal use of characters in database fields that get interpreted as mathtex (e.g. some of these column names include multiple $ signs) and I just want clean text output of those columns names in my chart legends. To do that on my side, I'm going to have to wrap all my DB API calls with string escaping. An rcParam would be far simpler.

  20. jklymak commented on Apr 22, 2022

    @jklymak
    Member

    @spillz Please open a new issue.

  21. oscargus commented on Apr 22, 2022

    @oscargus
    Member

    @spillz There will be one in 3.6: #22556

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions