How do I create a SymPy symbol that has a multi-character string for a subscript which renders properly with pretty printing?
The following render correctly:
symbols('tau_12')
symbols('tau_x')
but I cannot get the following to render the subscript correctly:
symbols('tau_xy')
How do I get a multi-character subscript?
Is this what you want?
xi1 = Symbol('x_i^{(1)}')
xi1
The problem is that Unicode only has a limited set of characters as subscripts (see https://en.wikipedia.org/wiki/Unicode_subscripts_and_superscripts#Other_superscript_and_subscript_characters). In particular, there is no Unicode character for subscript y. Your best bet if you want prettier printing is to use the IPython notebook or qtconsole, where you can get rendered math using MathJax or LaTeX.
Related
I'm using Sympy to do several symbolic computations in a Jupyter Notebook and I want to be able to get outputs of the form "x = [sympy expression] = [sympy expression]". If I just do something like
from sympy import symbols, diff
x = symbols('x')
y = diff(6*x**5)
y
It will display the value of y using nice textbook style notation. The problem is if I try to combine text with Sympy expressions. If I simply put a Sympy expression in a print statement, it doesn't preserve the formatting but will display the result using standard Python syntax (I've tried using pprint and all of Sympy's other print functions, but they didn't help). If I instead use the display function from IPython, that renders the Sympy expressions correctly, but it will also put them on separate lines from the text. So, for instance, if I do
display(f"y ={y}")
the "y =" will be on a separate line from the expression for y. If I have several Sympy expressions in one display statement, that results in things being needlessly broken up into several lines, which is a rather ugly output.
The only way I found around the unwanted line breaks is to wrap the Sympy expressions in IPython's Math function, which seems to convert the Sympy expressions to regular Python syntax (e.g. x² becomes x**2), then use regular expressions to convert the Python syntax to LaTex syntax, which the Math function will render properly (e.g. display(f'y = {re.sub('\*\*', '^', Math(y)}')). It works, but it's a lot of hassle. Is there an easier way?
Actually I figured it out, so I'm posting my solution in case anyone else has a similar question: the need for directly using regular expressions to convert the sympy expression to LaTex the Math can render can be avoided by using Sympy's LaTex function, which converts any sympy expression to LaTex syntax. So, doing, e.g.
from IPython.display import display, Math
from sympy import latex, symbols, diff
x = symbols('x')
y = diff(6*x**5)
display(Math(f' y = {latex(y)}'))
will give the single line output:
y = 30x⁴
which is exactly what I wanted (albeit, for more complicated expressions than the one I gave as an example).
I am running into some issues getting things to display correctly when combining string formating and tex rendering in python. I want to index a series of energy levels by integers. This works fine for single-digit integers, however when I try for example:
s = r"$E_{}$".format(10)
the result looks like E10 while I want it to look like E10. I have tried using double braces but this doesn't seem to work since
s = r"$E_{{}}$".format(10)
results in "E" without any subscript at all, and something like
s = r"$E_{{k}}$".format(k = 10)
predictably gives Ek.
To me it seems the problem here is that both the string formatting and Tex syntax make use of curly braces, and while doubling the braces does escape the formatting, this will not work for me, since I still want to insert the value of k somehow. Is there any way around this issue, or will I have to resort to the old school method of formatting strings?
Literal { can be included with {{ - and then you need another {} to get the formatting placeholder - so you need 3:
s = r"$E_{{{}}}$".format(10)
print(s)
Results in:
$E_{10}$
Which should be rendered into what you wanted.
I'm using python and matplotlib to generate graphical output.
I am creating multiple plots within a loop and would like the loop counter to serve as an index on the y-axis label. How do I get the loop counter (a variable) to appear as a subscript?
Here's what I have:
axis_ylabel = plt.ylabel(u"\u03b1 [\u00b0]", rotation='horizontal', position=(0.0,0.9))
resulting in:
α [°]
(I'm using unicode instead of Tex because dvipng is not available on this system.)
I would like something like this:
for i in range(1,3):
axis_ylabel = plt.ylabel(u"\u03b1" + str(i) + u" [\u00b0]", rotation='horizontal', position=(0.0,0.9))
No surprise, this gives:
α1 [°]
α2 [°]
What I really want is the numbers to be subscripts. How do I combine the conversion to a string with a command to create a subscript? Including a '_' is not recognized in the unicode environment to generate a subscript. Additionally, I still need python/matplotlib to recognize that this subscript-command should affect the following variable.
Any thoughts?
Edit
I got this far:
axis_ylabel = plt.ylabel(u"\u03b1" + r"$_" + str(i) + r"$" + u" [\u00b0]", rotation='horizontal', position=(0.0,0.9))
-- this results in a subscript character. However, it is NOT a conversion of the integer value but a different symbol.
Edit 2
I am using python 2.6.6 and matplotlib 0.99.1.1. Inserting any kind of string at <> in r"$<>$" will not result in the display of that string but an entirely different character. I have posted this issue as a new question.
Matplotlib ships its own mathematical expression engine, called mathtext.
From the documentation:
Note that you do not need to have TeX installed, since matplotlib
ships its own TeX expression parser, layout engine and fonts.
So maybe try to use the following:
for i in range(1,3):
plt.ylabel(
r"$\alpha_{:d} [\degree]$".format(i),
rotation='horizontal',
position=(0.0,0.9))
You can also use Unicode in mathtext:
If a particular symbol does not have a name (as is true of many of the
more obscure symbols in the STIX fonts), Unicode characters can also
be used:
ur'$\u23ce$'
I'm trying to add some axis-labels to a graph which contains the Greek letter 'rho'. To do this I want to use the LaTeX capability of Matplotlib but it seems to have a problem with the \rho symbol.
Here is a minimal example:
import matplotlib.pyplot as plt
from matplotlib import rc,rcParams
rc('text',usetex=True)
rcParams.update({'font.size': 16})
plt.plot([0,1,2,3,4],[0,1,4,9,16])
plt.xlabel('\rho A_i') # works if \rho is replaced with, for example, \sigma
plt.ylabel('Something else')
plt.show()
Upon running the first time I get a bunch of LaTeX errors and a blank figure window, running again shows the graph but the xlabel reads 'ho Ai ' where the i is subscript as expected.
The weird thing is if I replace \rho with something else, say, \sigma it shows up correctly. Can anybody tell me why it is not happy with my code example and how to fix it?
Thanks.
P.s. I tried putting the expression in $..$ but that changed nothing.
I think you are supposed to use raw strings, and use the $ signs as well. Try:
plt.xlabel(r'$\rho A_i$')
Be careful when you're using \n , \r and so on in a string. Those are commands for e.g. entering a new line etc.
https://docs.python.org/2/library/re.html
To make sure you don't use these regular expression operators put \\rho instead of \rho.
I'm using matplotlib to produce some graphics, and I'm using latex for the legends.
More specifically, I'm trying to use something like this:
loglog(x,x, '-r',label='$ \alpha $')
legend()
show()
However, this code does not present a legend on the figure, and gets error after I close the image.
I'm using the enthought package (for mac), but the error comes from the pylab/scipy.
The error the appears is exactly:
$ lpha $ (at char 0), (line:1, col:1)
However, if use the \mu or \gamma, it works well!! I only found about this problem on \beta and \alpha.
Does anyone knows what this can be? I believe python is interpreting "\a" as some character... but I don't know how should I debug / avoid it.
The issue is that \a and \b have special meaning inside a Python string literal.
I recommend that you use raw strings whenever there is a backslash embedded inside a string:
r'$ \alpha $'
In addition to using raw strings (as mentioned in the post above) you can also escape the backslash. So typing \\alpha and \\beta will also work.
Hi if your \alpha and \beta don't work on Latex
use $\alpha$
likewise $\beta$ so on.
hope it works