matplotlib tex renderer gives unexpected error - matplotlib

I am creating a scatter plot with color map based on some values and I am trying to make part of the x_axis label italic (inspired mostly by this post -> https://stackoverflow.com/a/8384685/1093485) but I am getting a LaTeX error that I can not explain myself, I would appreciate if anyone is able to explain what is going wrong with this chunk?
Minimum code required to reproduce problem here:
#! /usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
X = [1257.422648,1298.449197,1339.475746,1419.475471,1455.52309,1460.50202,1485.533655]
Y = [21.84637515,18.19617016,22.29456694,5.228978612,3.888695726,12.36598466,4.201838517]
Z = [44.02797944,9.758071204,21.58997772,64.53887544,53.09630431,8.461254471,291.4311435]
# Enable LaTeX style
rc('text',usetex=True)
# Plot the data
fig=plt.figure()
fig.patch.set_facecolor('white')
ax=fig.add_subplot(111)
s = ax.scatter(X,Y,c=np.log(Z))
ax.set_xlabel(r'Analyte \textit{m/z}')
ax.xaxis.labelpad = 7.5
cb = plt.colorbar(mappable=s,ax=ax)
plt.show()
Commenting the rc('text',usetex=True) causes the plot to show but obviously without italics. The whole traceback is rather large but seems to revolve around this part (if I read it correctly):
RuntimeError: LaTeX was not able to process the following string:
'$1450$'
Anyone have a suggestion on what to do to isolate the problem?

Related

matplotlib chart construction to suit use flask? (working example uses matplotlib.figure FigureCanvasAgg) can I construct errorbars?

I have a matplotlib chart working nicely as a python script. I need to create this chart style in flask. Can't use this method within flask as flask thread management doesn't play with matplotlib.
Oddly, the current method will run once successfully, subsequent runs will produce this error.
RuntimeError: main thread is not in main loop
So this is my desired chart format to produce in flask.
the code I'm using currently.
fig, ax = plt.subplots()
fig.subplots_adjust(bottom=0.29, top=.91)
ax.set_title(title)
ax.set_ylabel("y label text")
ax.set_xlabel('x label text')
ax.tick_params(axis='x', labelrotation = -80)
l = ax.plot(df_output['column1'])
y_error = df_output['column2']
plt.errorbar(list(df_output.index), \
list(df_output['column1']), \
yerr = y_error,fmt='o',ecolor = 'blue',color='blue')
fig.legend(l, loc=8, labels=labels)
#loc=2 = top left corner, loc=8 = 'lower center'
#plt.show()
plt.savefig(output_path+"/"+title+'_errorbars.png')
I found this example that works with flask
https://gist.github.com/illume/1f19a2cf9f26425b1761b63d9506331f
it uses this matplotlib charting syntax. Need to convert my old matplotlib format to suit the flask compatible format. Is this chart format possible via FigureCanvasAgg?
fig = Figure()
axis = fig.add_subplot(1, 1, 1)
print("type(axis):", type(axis))
x_points = data.iloc[:, 0]
y_points = data['mean minus sterility control mean']
axis.plot(x_points, y_points)
output = io.BytesIO()
FigureCanvasAgg(fig).print_png(output)
return Response(output.getvalue(), mimetype="image/png")
I'll admit to not being strong in building matpotlib charts. changing between chart building methods throws me.
I'm digging around the docs at moment.
https://matplotlib.org/stable/gallery/user_interfaces/canvasagg.html
I did find this Q&A (RuntimeError: main thread is not in main loop with Matplotlib and Flask)
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
while this appears to run for me. I want to move away from creating charts as files on the server, too much potential for file mismanagement, creating the chart as a io.BytesIO() output (or some format within the flask http response to user) is a much better solution.
(I'd like to keep at an image output, rather than change architecture to (say) a json output and constructing chart in client using javascript libraries)

Usetex in Matplotlib

When I try to obtain plots in which the axis (both formulae and text) are written in LaTeX standard roman font, I keep not obtaining the plot, but the code runs without warnings. In particular, this simple scatter with TeX code in the axis labels, in which I have put my better understanding of the documentation:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rc
x = np.linspace(0,1,100)
y = np.random.rand(100,1)
plt.rc('text', usetex=True)
plt.rc('font', family='roman')
plt.scatter(x, y, c='b', s=10)
plt.xlabel(r'$\lambda$ ($\AA$)',size='12')
plt.ylabel(r'$F_\alpha (W/m^2)$ ',size='12')
plt.title(r'A title in \LaTeX typography')
plt.show()
keeps yielding a message like <matplotlib.figure.Figure at 0x1f75d4750>, which I have met before, but I keep failing when trying to remedy this one. In addition, saving the plot (png or pdf) would not solve the issue, and if the problem is related to TeX, I have definitely not found any resource that can help. I use MacOS Sierra.

Change y-axis scaling fontsize in pandas dataframe.plot()

I am changing the font-sizes in my python pandas dataframe plot. The only part that I could not change is the scaling of y-axis values (see the figure below).
Could you please help me with that?
Added:
Here is the simplest code to reproduce my problem:
import pandas as pd
start = 10**12
finish = 1.1*10**12
y = np.linspace(start , finish)
pd.DataFrame(y).plot()
plt.tick_params(axis='x', labelsize=17)
plt.tick_params(axis='y', labelsize=17)
You will see that this result in the graph similar to above. No change in the scaling of the y-axis.
Ma
There are just so many features that you can control with the plotting capabilities of pandas, which leverages matplotlib. I found that seaborn is a lot easier to produce pretty charts, and you have a lot more control over the parameters of your plots.
This is not the most elegant solution, but it works; however, it has a seborn dependency:
%pylab inline
import pandas as pd
import seaborn as sns
import numpy as np
sns.set(style="darkgrid")
sns.set(font_scale=1.5)
start = 10**12
finish = 1.1*10**12
y = np.linspace(start , finish)
pd.DataFrame(y).plot()
plt.tick_params(axis='x', labelsize=17)
plt.tick_params(axis='y', labelsize=17)
I use Jupyter Notebook an that's why I use %pylab inline. The key element here is the use of
font_scale=1.5
Which you can set to whatver you want that produces your desired result. This is what I get:

Graphing matplotlib with Python code in a R Markdown document

Is it possible to use Python matplotlib code to draw graph in RStudio?
e.g. below Python matplotlib code:
import numpy as np
import matplotlib.pyplot as plt
n = 256
X = np.linspace(-np.pi,np.pi,n,endpoint=True)
Y = np.sin(2*X)
plt.plot (X, Y+1, color='blue', alpha=1.00)
plt.plot (X, Y-1, color='blue', alpha=1.00)
plt.show()
Output graph will be:
Then I need to write a R Markdown to include these code and generate graph automatically after knitting the markdown.
install.packages('devtools') first, get install_github function
install_github("rstudio/reticulate") install the dev version of reticulate
in r markdown doc, use code below to enable the function.
```{r setup, include=FALSE}
library(knitr)
library(reticulate)
knitr::knit_engines$set(python = reticulate::eng_python)
```
Try it , you will get what you want and don't need to save any image.
One possible solution is save the plot as a image, then load the file to markdown.
### Call python code sample
```{r,engine='python'}
import numpy as np
import matplotlib.pyplot as plt
n = 256
X = np.linspace(-np.pi,np.pi,n,endpoint=True)
Y = np.sin(2*X)
fig, ax = plt.subplots( nrows=1, ncols=1 )
ax.plot (X, Y+1, color='blue', alpha=1.00)
ax.plot (X, Y-1, color='blue', alpha=1.00)
#plt.show()
fig.savefig('foo.png', bbox_inches='tight')
print "finished"
```
Output image:
![output](foo.png)
#### The End
Output:
You can do that with reticulate, but most time in trying to follow a tutorial in doing that you may encounter some technicalities that weren't sufficiently explained.
My answer is a little late but I hope it's a thorough walkthrough of doing it the right way - not rendering it and then loading it as a png but have the python code executed more "natively".
Step 1: Configure Python from RStudio
You want to insert an R chunk, and run the following code to configure the path to the version of Python you want to use. The default python that comes shipped with most OS is usually the outdated python 2 and is not where you install your packages. That is the reason why it's important to do this, to make sure Rstudio will use the specified python instance where your matplotlib library (and the other libraries you will be using for that project) can be found:
library(reticulate)
# change the following to point to the desired path on your system
use_python('/Users/Samuel/anaconda3/bin/python')
# prints the python configuration
py_config()
You should expect to see that your session is configured with the settings you specified:
python: /Users/Samuel/anaconda3/bin/python
libpython: /Users/Samuel/anaconda3/lib/libpython3.6m.dylib
pythonhome: /Users/Samuel/anaconda3:/Users/Samuel/anaconda3
version: 3.6.3 |Anaconda custom (64-bit)| (default, Oct 6 2017, 12:04:38) [GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)]
numpy: /Users/Samuel/anaconda3/lib/python3.6/site-packages/numpy
numpy_version: 1.15.2
python versions found:
/Users/Samuel/anaconda3/bin/python
/usr/bin/python
/usr/local/bin/python
/usr/local/bin/python3
/Users/Samuel/.virtualenvs/r-tensorflow/bin/python
Step 2: The familiar plt.show
Add a Python chunk (not R!) in your R Markdown document (see attached screenshot) and you can now write native Python code. This means that the familiar plt.show() and plt.imshow() will work without any extra work. It will be rendered and can be compiled into HTML / PDF using knitr.
This will work:
plt.imshow(my_image, cmap='gray')
Or a more elaborated example:
import numpy as np
import matplotlib.pyplot as plt
import os
import cv2
DATADIR = '/Users/Samuel/Datasets/PetImages'
CATEGORIES = ['Dog', 'Cat']
for category in CATEGORIES:
path = os.path.join(DATADIR, category) # path to cat or dog dir
for img in os.listdir(path):
img_array = cv2.imread(os.path.join(path,img), cv2.IMREAD_GRAYSCALE)
plt.imshow(img_array, cmap='gray')
plt.show()
break
break
Output:
Step 3: Knit to HTML / PDF / Word etc
Proceed to knit as usual. The end product is a beautifully formatted document done in Python code using R Markdown. RStudio has come a long way and I'm surprised the level of support it has for Python code isn't more known so hoping anyone that stumbled upon this answer will find it informative and learned something new.
I have been working with reticulate and R Markdown and you should specify your virtual environment. For example my R Markdown starts as follows:
{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, warning = FALSE, cache.lazy = FALSE)
library(reticulate)
use_condaenv('pytorch') ## yes, you can run pytorch and tensor flow too
Then you can work in either language. So, for plotting with matplotlib, I have found that you need the PyQt5 module to make it all run smoothly. The following makes a nice plot inside R Markdown - it's a separate chunk.
{python plot}
import PyQt5
import numpy as np
import pandas as pd
import os
import matplotlib.pyplot as plt
from matplotlib.pyplot import figure
data = pd.read_csv('Subscriptions.csv',index_col='Date', parse_dates=True)
# make the nice plot
# set the figure size
fig = plt.figure(figsize = (15,10))
# the series
ax1 = fig.add_subplot(211)
ax1.plot(data.index.values, data.Opens, color = 'green', label = 'Opens')
# plot the legend for the first plot
ax1.legend(loc = 'upper right', fontsize = 14)
plt.ylabel('Opens', fontsize=16)
# Hide the top x axis
ax1.axes.get_xaxis().set_visible(False)
####### NOW PLOT THE OTHER SERIES ON A SINGLE PLOT
# plot 212 is the MI series
# plot series
ax2 = fig.add_subplot(212)
ax2.plot(data.index.values, data.Joiners, color = 'orange', label = 'Joiners')
# plot the legend for the second plot
ax2.legend(loc = 'upper right', fontsize = 14)
# set the fontsize for the bottom plot
plt.ylabel('Joiners', fontsize=16)
plt.tight_layout()
plt.show()
You get the following from this:
I don't have the reputation points to add a comment, but Bryan's answer above was the only one to work for me. Adding plt.tight_layout() made the difference. I added that line to the following simple code and the plot displayed.
{python evaluate}
plt.scatter(X_train, y_train, color = 'gray')
plt.plot(X_train, regresssion_model_sklearn.predict(X_train), color = 'red')
plt.ylabel('Salary')
plt.xlabel('Number of Years of Experience')
plt.title('Salary vs. Years of Experience')
plt.tight_layout()
plt.show()

Using matplotlib's patches in julia

Using the output from a computation in julia (working in IJulia), I'd like to draw a figure using matplotlib's patches module (via Steven Johnson's PyCall and PyPlot packages). I've read several related posts on stackoverflow, but I can't seem to get a minimum working example. Could somebody post a simple example? Say something that plots a rectangle or an ellipse?
Here's a python example that works:
#!/usr/local/bin/python3
import matplotlib.pyplot
import matplotlib.patches
cfig = matplotlib.pyplot.figure()
c = cfig.add_subplot(111)
c.set_aspect("equal")
p = matplotlib.patches.Circle([0.5,0.5],0.40,fc="blue",ec="red",linewidth=5,zorder=0)
c.add_patch(p)
cfig.savefig("circle.pdf",bbox_inches="tight")
My attempt at the same thing in Julia stalls at the subplot
using PyPlot
using PyCall
#pyimport matplotlib.patches as patches
cfig = figure()
c = cfig.add_subplot(111)
Which yields:
type Figure has no field add_subplot
while loading In[19], in expression starting on line 4
OK, thanks to jverzani's link, I was able to piece together a working example. I'm still a little shaky on the syntax in Julia for setting all the options for the plot.
using PyPlot
using PyCall
#pyimport matplotlib.patches as patch
cfig = figure()
ax = cfig[:add_subplot](1,1,1)
ax[:set_aspect]("equal")
c = patch.Circle([0.5,0.5],0.4,fc="blue",ec="red",linewidth=.5,zorder=0)
ax[:add_artist](c)
cfig[:savefig]("circle.png")