- Notifications
You must be signed in to change notification settings - Fork 104
matplotlib
This page describes ways to make PythonTeX work with matplotlib more conveniently.
Suppose you have the following code in your document:
x=linspace(0, pi)
plt.plot(x, sin(x), label='sin(x)')
plt.plot(x, cos(x), label='cos(x)')If you want to quickly view these plots in your document, you could call plt.legend() and plt.savefig('foo.pdf') and then write the LaTeX code to include a figure. To simplify this process the following helper functions may be useful. (Modify them to suit your needs!)
# Set the prefix used for figure labelsfig_label_prefix='fig'# Track figure numbers to create unique auto-generated namesfig_count=0defsavefig(name='', legend=False, fig=None, ext='.pdf'):
''' Save the current figure (or `fig`) to file using `plt.savefig()`. If called with no arguments, automatically generate a unique filename. Return the filename. '''# Get name (without extension) and extensionifnotname:
globalfig_count# `pytex.id` is a unique identifier for the session;# it's `<family>_<session>_<restart>`name='auto_fig_{}-{}'.format(pytex.id, fig_count)
fig_count+=1else:
iflen(name) >4andname[:-4] in ['.pdf', '.svg', '.png', '.jpg']:
name, ext=name.rsplit('.', 1)
# Get current figure if figure isn't specifiedifnotfig:
fig=gcf()
# Put a nice legend on top of the figure (you may need to adjust this!)# Only create legend if axis has labelsiflegendandlen(fig.gca().get_legend_handles_labels()[0]) !=0: foraxinfig.axes:
ifax.is_first_row():
box=ax.get_position()
ax.set_position([box.x0, box.y0, box.width, box.height*0.9])
leg=ax.legend(loc="upper center", bbox_to_anchor=(0.5, 1.04), ncol=3, bbox_transform=fig.transFigure, frameon=False)
fig.savefig(name+ext)
fig.clf()
returnnamedeflatex_environment(name, content='', option=''):
''' Simple helper function to write the `\begin...\end` LaTeX block. '''return'\\\\begin{%s}%s\n%s\n\\\\end{%s}'% (name, option, content, name)
deflatex_figure(name=None, caption='', label='', width=0.8):
'''' Auto wrap `name` in a LaTeX figure environment. Width is a fraction of `\textwidth`. '''ifnotname:
name=savefig()
content='\\\\centering\n'content+='\\\\includegraphics[width=%f\\\\textwidth]{%s}\n'% (width, name)
ifnotlabel:
label=nameifcaptionandnotcaption.rstrip().endswith('.'):
caption+='.'# `\label` needs to be in `\caption` to avoid issues in some casescontent+="\\\\caption{%s\\\\label{%s:%s}}\n"% (caption, fig_label_prefix, label)
returnlatex_environment('figure', content, '[htp]')The above code block can be included in your document's preamble via
\begin{pythontexcustomcode}[begin]
...
\end{pythontexcustomcode}Or you may store it in a file and import it in the usual way. Say you have a src directory alongside your document and the above code is in a file python_preamble.py:
\begin{pythontexcustomcode}[begin]{pylab}
# Might want sys.path.insert(1, '../src/') in some cases# But then it would probably be better to use virtualenvsys.path.append('../src/')
frompython_preambleimport*
\end{pythontexcustomcode}The figure for the example considered at the beginning may now be created very simply:
\begin{pylabcode}
x=linspace(0, pi)
plt.plot(x, sin(x), label='sin(x)')
plt.plot(x, cos(x), label='cos(x)')
name=savefig()
fig=latex_figure(name)
\end{pylabcode}
\pylab{fig}Of course, we could also just print the figure, using print(latex_figure()) at the end of the pylabcode environment or using \pylab{latex_figure()} after the end of the environment.
Matplotlib 1.2 has a new pgf backend. This may be useful when you want to create graphics that are compiled at the same time as the document (for better font integration, etc.).