\frac{}{} doesn't work in plt.text? - matplotlib

I am trying to add a text to my plot, using latex. Latex and \frac{}{} works well in titles and labels, but I can not get it work in plt.text(). I tried both, using raw or double backslash.
import matplotlib.pyplot as plt
plt.axhline(x=30, c='k')
plt.text(0,0,r'$\frac{\Gamma_M}{\Gamma_D}$ = 10')
plt.xlabel(r'$\frac{\Gamma_M}{\Gamma_D}$')
It works for label (if you outcomment text line) but not for text, gives me this output:
KeyError: '\\Gamma_M'

It is interpreting the {} as part of the python format strings, not LaTeX. Use double braces instead:
plt.text(0,0,r'$\frac{{\Gamma_M}}{{\Gamma_D}}$ = 10')

Related

How to print the content of variables inside math expression using Latex and Sympy in Matplotlib?

I am working on a software that solve an engineering problem. The software should printout the calculation for the user in a pretty mathematical expression format. I used Matplotlib,Latex and Sympy in PyQt and succeeded to do everything I wanted except for displaying the values of the variables in the form of a fracture (please see the picture below to understand what I mean). Also, I would like to know how to control the font size and style of the latex text(see the picture). below is a part of the code.
See this picture
def Calculate(self):
plt.rc('mathtext', fontset='cm')
self.right_column_stiffness = int(self.lineEdit_3.text())
self.left_column_stiffness = int(self.lineEdit_4.text())
self.beam_load = int(self.lineEdit_4.text())
w=self.beam_load*(1000/12)
g=386.1
self.mass = w/g
formula=r'm=\frac{w}{g}='
self.result_figure.text(.05, .85, r'${}$'.format(formula+latex(w)), fontsize=20)
[enter image description here][1]
self.result_canvas.draw()
There are two questions you have asked:
The font size of latex representation of fractions can be changed in two ways. First is to surround the fraction latex code with \displaystyle block.
formula = r'm={\displaystyle\frac{w}{g}}'
Other option is to change '${}$' to \[{}\] in the following line.
self.result_figure.text(.05, .85, r'\[{}\]'.format(formula+latex(w)), fontsize=20)
In order to print the values contained in variables as a fraction rather than the final answer, you will have to manually construct another latex text.
value = r'${{\displaystyle\frac{{{0}}}{{{1}}}}}$'.format(w,g)
Here is my example code:
import matplotlib.pyplot as plt
from matplotlib import rc # Added these two lines
rc('text', usetex=True)
formula = r'm=\frac{{w}}{{g}} = \frac{{{0}}}{{{1}}}'.format(100,20)
plt.plot( [0,1,2,3], [0,1,2,3], '.')
plt.text(1,1,r'\[{}\]'.format(formula),fontsize=20)
plt.show()
Which gives the following result

Matplotlib: emoji font does not work when using backend_pdf

I want to use the emoji-font "Symbola.ttf" to label my plots. This does work when I use plt.show(). But it does not work when using the backend_pdf. Only two emojis are shown in a mixed up order.
example images:
when using plt.show():
when using the backend_pdf:
example code:
Here is my code to produce these examples:
import matplotlib.backends.backend_pdf
import matplotlib.pyplot as plt
import emoji
from matplotlib.font_manager import FontProperties
emojis = [emoji.EMOJI_UNICODE[e] for e in list(emoji.EMOJI_UNICODE.keys())[620:630]]
prop = FontProperties(fname='./Symbola.ttf', size=30)
# backend_pdf plot
pdf = matplotlib.backends.backend_pdf.PdfPages("output.pdf")
plt.xticks(range(len(emojis)), emojis, fontproperties=prop)
pdf.savefig()
pdf.close()
# plt.show() plot
plt.xticks(range(len(emojis)), emojis, fontproperties=prop)
plt.show()
I'm running this on a Linux machine.
I think I have found the problem. It seems that my Symbola.ttf was broken. When I use this .ttf file everything works great.

r'\textbf{}'.format() doesn't work for string variable with Latex in Matplotlib

Hi I'm trying to enable bold font for labels in Matplotlib with Latex text rendering. I am able to do this for numerical variables (integers, floats) but failed with string variable.
So this works:
a = 1
plt.plot(X, y, label=r'\textbf{}'.format(a))
but this doesn't:
a = 'text'
plt.plot(X, y, label=r'\textbf{}'.format(a))
I know I can do this:
plt.plot(X, y, label=r'\textbf{text}')
But how can I use the format for a string variable?
Thanks!
You need to escape the curly brackets of the latex command, since the .format function uses those brackets to determine where to put its argument in the text.
Consider e.g.
r'\textbf{}'.format("something")
which results in
"\textbfsomething"
This is of course no valid latex command. On the other hand
r'\textbf{}'.format(9)
results in
"\textbf9"
which is a valid latex command. To be on the save side, always escape all curly brackets.
import matplotlib.pyplot as plt
plt.rcParams["text.usetex"] = True
a = 1
plt.plot([1,2], [2,3], label=r'\textbf{{{}}}'.format(a))
a = 'text'
plt.plot([1,2], [1,2], label=r'\textbf{{{}}}'.format(a))
plt.legend()
plt.show()

Matplotlib - using variables in LateX expressions

I would like to build an expression using LateX formatting, where some numbers appear but are expressed in terms of a variable in the LateX expression.
The actual goal is to use this in the axes.annotate() method, but for the sake of discussion here is a principle code:
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-5, 5, 0.05)
fig = plt.plot(x, x**2)
plt.grid(True)
g = 3
plt.xlabel(r'$test {}$'.format(g))
plt.show()
This is OK.The value of g is passed to the expression.
However, what about using \frac{}{} and other constructs?
Substituting the xlabel() string above with:
plt.xlabel(r'$test \frac{1}{}$'.format(g))
gives:
IndexError: tuple index out of range
I understand that something is going on with the use of curly braces and have tried a couple of variants, but nothing worked so far.
Curly braces can be escaped by doubling, but format removes a pair after substituting g (and frac expects its arguments in curly braces) so you need three pairs for the denominator
plt.xlabel(r'$test \frac{{1}}{{{}}}$'.format(g))
You can also bypass the curly braces method by using the '.replace()' method
r'$\mathregular{T_{s1}}$'.replace('s1', 'toto')
which yields
'$\\mathregular{T_{toto}}$'

Draw points and lines in legend text?

Is there any possibility to get lines and points into a legend text in matplotlib?
I had something in mind like the following
x=np.linspace(0,10,100)
ys=np.sin(x)
yc=np.cos(x)
pl.plot(x,ys,'--',label='sin')
pl.plot(x,yc,':',label='derivative of --')
pl.legend()
pl.show()
except that instead of the -- there should be the same symbol with the corresponding color just as in front of the legend label sin.
After reading around in the matplotlib source code I finally found a solution that works perfect for me and that does not need any position tweaking etc. as it used matplotlibs internal V- and HPackers.
import numpy as np
import pylab as pl
x=np.linspace(0,10,100)
ys=np.sin(x)
yc=np.cos(x)
pl.plot(x,ys,'--',label='sin')
pl.plot(x,yc,':',label='derivative of')
leg=pl.legend()
# let the hacking begin
legrows = leg.get_children()[0].get_children()[1]\
.get_children()[0].get_children()
symbol = legrows[0].get_children()[0]
childs = legrows[1].get_children().append(symbol)
pl.show()
The result looks as follows:
This is a little bit of a hack, but it accomplishes your goal and places all of the pieces (i.e. the legend and the text) on the plot in the appropriate order.
import pylab
pl.plot(x,ys,'--',label='sin', color='green')
pl.plot(x,yc,':',label='derivative of --',color='blue')
line1= pylab.Line2D(range(10), range(10), marker='None', linestyle='--',linewidth=2.0, color="green")
line2= pylab.Line2D(range(10), range(10), marker='None', linestyle=':',linewidth=2.0, color="blue")
leg = pl.legend((line1,line2),('sin','derivative of '),numpoints=1, loc=1)
pylab.text(9.4, 0.73, '- -', color='green')
leg.set_zorder(2)
pl.show()
Instead of relying on the default colors for the lines, I set them such that they can be referenced specifically in the legend. There are extra spaces left in the text for 'the derivative' for the second line in the legend, so we can place text (aka corresponding symbol/color of the sin line) on top of it. Then you specify the symbol/color of the text and place it such that it lines up with the text in the legend. Finally you specify the order, via zorder, to set the text on top.