Reputation: 8128
Using format strings in Python I can easily print a number in "scientific notation", e.g.
>> print '%g'%1e9
1e+09
What is the simplest way to format the number in LaTeX format, i.e. 1\times10^{+09}?
Upvotes: 17
Views: 12305
Reputation: 11
I wrote a super simple python3 package called real2tex
.
You can install it with pip:
pip install real2tex
And use it as follows:
from real2tex import real2tex
tex = real2tex(1.2345e-6, precision=2)
print(tex) # "1.23 \cdot 10^{\minus 6}"
If you are interested in the implementation, here I explain how it works.
Firtst we have a function that takes a real number and returns a tuple representing
it in scientific notation. It returns the mantissa, the exponent,
and a boolean indicating if the exponent is negative.
To do this, I exploit the built-in format specifier "{:.{precision}e}"
that converts the number to a string representing it in scientific notation. The
variable precision
controls the number of decimal places in the mantissa (e.g., if precision=2
, it
will
return something like "1.23e-6"). Once i have this string, I parse it to extract the
mantissa, the exponent, and the sign of the exponent:
def scientific_notation(num: Real, precision: int = 2) -> tuple[str, str, bool]:
num_str = f"{num:.{precision}e}"
mantissa, exponent = num_str.split("e")
negative_exponent = True if exponent[0] == "-" else False
exponent = exponent[1:]
# Remove leading zeros in the exponent
exponent = exponent.lstrip("0")
if len(exponent) == 0:
exponent = "0"
# Remove trailing zeros in the mantissa
mantissa = mantissa.rstrip("0")
# Remove trailing dot in the mantissa
mantissa = mantissa.rstrip(".")
# Remove sign if mantissa is zero
if mantissa == "-0":
mantissa = "0"
return mantissa, exponent, negative_exponent
Once I have the mantissa, the exponent, and the sign of the exponent, it is easy to convert this information to LaTeX format:
def real2tex(
num: Real, precision: int = 2, multiply_symbol: str = "\\cdot", no_10_to_the_zero: bool = True
) -> str:
mantissa, exponent, negative_exponent = scientific_notation(num, precision)
if negative_exponent:
exponent = f"\\minus {exponent}"
if exponent == "0" and no_10_to_the_zero:
return f"{mantissa}"
return f"{mantissa} {multiply_symbol} 10^{{{exponent}}}"
If you want to edit the code or report an issue, you can find it on GitHub.
Upvotes: 1
Reputation: 473
Install num2tex:
pip install num2tex
and use it as so:
>>> from num2tex import num2tex
>>> '{:.0e}'.format(num2tex(1e9))
'1 \\times 10^{9}'
num2tex
inherits from str
so the format
function can be used in the same way.
You can also change the format of the exponent by using num2tex.configure()
(adding this in response to @Matt's comment).
>>>from num2tex import num2tex
>>>from num2tex import configure as num2tex_configure
>>>num2tex_configure(exp_format='cdot')
>>>num2tex(1.3489e17)
'1.3489 \cdot 10^{17}'
>>>num2tex_configure(exp_format='parentheses')
'1.3489 (10^{17})'
As of now this is undocumented in the GitHub, I'll try to change this soon!
Disclaimer: After using (and upvoting) Lauritz V. Thaulow's answer for a while (for Jupyter, Matplotlib etc.) I thought it would be better for my workflow to write a simple Python module, so I created num2tex on GitHub and registered it on PyPI. I would love to get some feedback on how to make it more useful.
Upvotes: 8
Reputation: 50985
The siunitx LaTeX package solves this for you by allowing you to use the python float value directly without resorting to parsing the resulting string and turning it into valid LaTeX.
>>> print "\\num{{{0:.2g}}}".format(1e9)
\num{1e+09}
When the LaTeX document is compiled, the above code will be turned into
. As andybuckley points out in the comments, the plus sign might not be accepted by siunitx (I've not tested it), so it may be necessary to do a .repace("+", "")
on the result.
If using siunitx
is somehow off the table, write a custom function like this:
def latex_float(f):
float_str = "{0:.2g}".format(f)
if "e" in float_str:
base, exponent = float_str.split("e")
return r"{0} \times 10^{{{1}}}".format(base, int(exponent))
else:
return float_str
Testing:
>>> latex_float(1e9)
'1 \\times 10^{9}'
Upvotes: 29
Reputation: 157314
You can write a frexp10
function:
def frexp10(x):
exp = int(math.floor(math.log10(abs(x))))
return x / 10**exp, exp
Formatting in LaTeX style is then:
'{0}^{{{1:+03}}}'.format(*frexp10(-1.234e9))
Upvotes: 6