garrettj403 / SciencePlots

Matplotlib styles for scientific plotting
MIT License
6.96k stars 700 forks source link

[Feature] siunitx mplstyle #101

Open fnemina opened 1 year ago

fnemina commented 1 year ago

Hello, hope you are doing great.

There is this package siunitx which allows for a better usage of units in latex. This allows for different usage of units inside latex and to be more consistent in their use inside and outside of equations.

I believe it would be easy to implement in SciencePlots as an additional mplstyle.

Proposal

For this it could be easy to create a latex-siunitx.mplstyle inside the misc folder with the line

text.latex.preamble :\usepackage{amsmath} \usepackage{amssymb} \usepackage{siunitx}

Example

import numpy as np
import matplotlib.pyplot as plt
import scienceplots

x = np.linspace(0.75, 1.25, 201)

def model(x, p):
    return x ** (2 * p + 1) / (1 + x ** (2 * p))

With the current implementation units would be like

pparam = dict(xlabel='Voltage (mV)', ylabel=r'Current ($\mu$A)')

with plt.style.context(['science']):
    fig, ax = plt.subplots()
    for p in [10, 15, 20, 30, 50, 100]:
        ax.plot(x, model(x, p), label=p)
    ax.legend(title='Order')
    ax.autoscale(tight=True)
    ax.set(**pparam)
    fig.savefig('fig01.png', dpi=300)
    plt.close()

fig01

with the new implementation it would change to

pparam = dict(xlabel=r'Voltage (\si{\milli\volt})', ylabel=r'Current (\si{\micro\ampere})')

with plt.style.context(['science','latex-siunitx']):
    fig, ax = plt.subplots()
    for p in [10, 15, 20, 30, 50, 100]:
        ax.plot(x, model(x, p), label=p)
    ax.legend(title='Order')
    ax.autoscale(tight=True)
    ax.set(**pparam)
    fig.savefig('fig01-siunitx.png', dpi=300)
    plt.close()

fig01-siunitx

Caveats

The only problem I seem to find with this is that if another style changes the text.latex.preamble line it would clash. It would be a problem for nature, russian-font, turkish-font, latex-sans, pgf and sans. Also it wouldn't work with styles that don't use latex like notebook.

Maybe this could be worked around in some way.

Best, Fran

echedey-ls commented 1 year ago

I feel the problem with the preambles is impossible to tackle down. It's more likely something that could be resolved on the matplotlib interface side.

BTW, matplotlib provides a way to use math text without latex that is much faster, so pursuing this change may not have a broad impact in the long term. Anyways, I don't want to discourage you. Feel free to open a PR. Don't forget to add text.usetex : True so it can be used as a stand-alone style.

WhiteSymmetry commented 5 months ago

Turkish font is working for latex-siunitx.

sudo apt-get install texlive-science (for siunitx – A comprehensive (SI) units package) apt-cache show texlive-science | grep siunitx siunitx -- A comprehensive (SI) units package.

import numpy as np import matplotlib.pyplot as plt import scienceplots

x = np.linspace(0.75, 1.25, 201)

def model(x, p): return x * (2 p + 1) / (1 + x * (2 p))

pparam = dict(xlabel=r'Voltaj/Gerilim (\si{\milli\volt})', ylabel=r'Akım (\si{\micro\ampere})')

with plt.style.context(['science','latex-siunitx']): fig, ax = plt.subplots() for p in [10, 15, 20, 30, 50, 100]: ax.plot(x, model(x, p), label=p) ax.legend(title='Düzen: öçüğşıÖÇÜĞŞİ') ax.autoscale(tight=True) ax.set(**pparam) fig.savefig('fig01-siunitx-tr.png', dpi=300) plt.close()

fig01-siunitx-tr

WhiteSymmetry commented 5 months ago

I feel the problem with the preambles is impossible to tackle down. It's more likely something that could be resolved on the matplotlib interface side.

BTW, matplotlib provides a way to use math text without latex that is much faster, so pursuing this change may not have a broad impact in the long term. Anyways, I don't want to discourage you. Feel free to open a PR. Don't forget to add text.usetex : True so it can be used as a stand-alone style.

Average execution time of the code:

  1. only Matplotlib 0.403068066-0.67 sn & 7.97-8.08 µs ± 50.7 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
  2. no-latex, no-grid 0.454268694-0.672160387 sn & 13.6 µs ± 108 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
  3. Science-Latex no-grid 0.639259100-8.895558834 sn & 78.4 µs ± 404 ns per loop (mean ± std. dev. of 7 runs, 10,000 loops each)