Matplotlib - using variables in LateX expressions - matplotlib

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}}$'

Related

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

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')

change scientific notation abbreviation of y axis units to a string

First I would like to apologize as I know I am not asking this question correctly (which is why I cant find what is likely a simple answer).
I have a graph
As you can see above the y axis it says 1e11 meaning that the units are in 100 Billions. I would like to change the graph to read 100 Billion instead of 1e11.
I am not sure what such a notation is called.
To be clear I am not asking to change the whole y axis to number values like other questions I only want to change the top 1e11 to be more readable to those who are less mathematical.
ax.get_yaxis().get_major_formatter().set_scientific(False)
results in an undesired result
import numpy as np
from matplotlib.ticker import FuncFormatter
def billions(x, pos):
return '$%1.1fB' % (x*1e-9)
formatter = FuncFormatter(billions)
ax.yaxis.set_major_formatter(formatter)
located from https://matplotlib.org/examples/pylab_examples/custom_ticker1.html
produces

Numpy gradient with non uniform spacing

I got something wrong going on :
import numpy as np
import matplotlib.pyplot as plt
x = np.concatenate((np.linspace(0,1,100),np.linspace(1,2,50)));
f = np.power(x,2);
df = 2*x;
Df = np.gradient(f,x);
plt.plot(x,df,'r', x,Df,'b');plt.show()
This is what I get :
Otherwise things work ok if using linearly spaced array and not using argument x.
Any suggestions?
I think this is because numpy versions before 1.13 expect the "x" argument to be the constant grid spacing (see https://docs.scipy.org/doc/numpy-1.11.0/reference/generated/numpy.gradient.html#numpy.gradient). Even though the earlier versions expect a scalar dx, they do not check for this, and the result is np.gradient(f) / x, which is a valid division. This is pretty annoying since code written for numpy 1.13 may run on earlier versions with incorrect output and no errors.

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()

jupyter notebook prints output even when suppressed

Why is it printing the bins from the histogram?
Shouldn't the semicolon suppress it?
In [1]
import numpy as np
import matplotlib.pyplot as plt
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all";
In [2]
%matplotlib inline
data ={'first':np.random.rand(100),
'second':np.random.rand(100)}
fig, axes = plt.subplots(2)
for idx, k in enumerate(data):
axes[idx].hist(data[k], bins=20);
You've set InteractiveShell.ast_node_interactivity = "all";, so you've set all nodes to have ast interactivity enabled. So you get the values of data = {..}
And ; works only for the last top level expression, axes[idx].hist(data[k], bins=20); is not a top level expression, as it is nested in the for, the last top level node is the for, which is a statement.
Simply add a last no-op statement, and end it with ;
%matplotlib inline
data ={'first':np.random.rand(100),
'second':np.random.rand(100)};
fig, axes = plt.subplots(2);
for idx, k in enumerate(data):
axes[idx].hist(data[k], bins=20)
pass; # or None; 0; "foo"; ...
And you won't have any outputs.
Use codetransformer %%ast magic to quickly see the ast of an expression.
If you read the documentation, you will see exactly what it returns - a three item tuple described below. You can display it in the notebook by placing a ? at the end of the call to the histogram. It looks like your InteractiveShell is making it display. Normally, yes a semicolon would suppress the output, although inside of a loop it would be unnecessary.
Returns
n : array or list of arrays
The values of the histogram bins. See normed and weights
for a description of the possible semantics. If input x is an
array, then this is an array of length nbins. If input is a
sequence arrays [data1, data2,..], then this is a list of
arrays with the values of the histograms for each of the arrays
in the same order.
bins : array
The edges of the bins. Length nbins + 1 (nbins left edges and right
edge of last bin). Always a single array even when multiple data
sets are passed in.
patches : list or list of lists
Silent list of individual patches used to create the histogram
or list of such list if multiple input datasets.