savefig PGF - RuntimeError: Cannot get window extent w/o renderer - python

I'm trying to save a figure in pyplot with tight margins.
The following code works perfectly with a PDF output:
from matplotlib import pyplot as plt
plt.plot(1)
plt.savefig('test.pdf', bbox_inches='tight')
But not with PGF output
plt.savefig('test.pgf', bbox_inches='tight')
as it returns RuntimeError: Cannot get window extent w/o renderer.
Why is this happening and is there a way to work around it?
matplotlib 1.3.0rc2 on Ubuntu 13.04
python -c "from matplotlib import pyplot as plt; plt.plot(1); plt.savefig('test.pgf', bbox_inches='tight');"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "PYTHONPATH/matplotlib-1.3.0rc2-py2.7-linux-x86_64.egg/matplotlib/pyplot.py", line 561, in savefig
return fig.savefig(*args, **kwargs)
File "PYTHONPATH/matplotlib-1.3.0rc2-py2.7-linux-x86_64.egg/matplotlib/figure.py", line 1410, in savefig
self.canvas.print_figure(*args, **kwargs)
File "PYTHONPATH/matplotlib-1.3.0rc2-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4agg.py", line 161, in print_figure
FigureCanvasAgg.print_figure(self, *args, **kwargs)
File "PYTHONPATH/matplotlib-1.3.0rc2-py2.7-linux-x86_64.egg/matplotlib/backend_bases.py", line 2169, in print_figure
bbox_inches = self.figure.get_tightbbox(renderer)
File "PYTHONPATH/matplotlib-1.3.0rc2-py2.7-linux-x86_64.egg/matplotlib/figure.py", line 1551, in get_tightbbox
bb.append(ax.get_tightbbox(renderer))
File "PYTHONPATH/matplotlib-1.3.0rc2-py2.7-linux-x86_64.egg/matplotlib/axes.py", line 9153, in get_tightbbox
bb_xaxis = self.xaxis.get_tightbbox(renderer)
File "PYTHONPATH/matplotlib-1.3.0rc2-py2.7-linux-x86_64.egg/matplotlib/axis.py", line 1055, in get_tightbbox
renderer)
File "PYTHONPATH/matplotlib-1.3.0rc2-py2.7-linux-x86_64.egg/matplotlib/axis.py", line 1038, in _get_tick_bboxes
extent = tick.label1.get_window_extent(renderer)
File "PYTHONPATH/matplotlib-1.3.0rc2-py2.7-linux-x86_64.egg/matplotlib/text.py", line 751, in get_window_extent
raise RuntimeError('Cannot get window extent w/o renderer')
RuntimeError: Cannot get window extent w/o renderer

By the way, there is a workaround. Normally the extent of PGF/TikZ images is adjusted automatically so it matches the drawing. For preserving the figure size intended by matplotlib, these lines are added to the output:
\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{8.000000in}{6.000000in}}%
\pgfusepath{use as bounding box}%
If you remove these lines at the very top from the PGF output you should get rid of any additional space around the figure.
Using plt.tight_layout(), or better plt.figure(tight_layout=True) in version 1.3, is another way to do that (which works perfectly with PGF and PGF->PDF), although it is a bit different. It recalculates the figure's layout so it fits to the given figure size. I usually prefer that method because it also eliminates problems like overlapping text elements.

Related

Cartopy not running even with basic introductory example

I have installed Cartopy and am now trying to run the basic example code snippet on the tutorial website just to check everything is working:
ax = plt.axes(projection=ccrs.PlateCarree())
ax.coastlines()
plt.savefig('coastlines.pdf')
plt.savefig('coastlines.png')
plt.show()
I get the following ValueError back:
Traceback (most recent call last):
File "/Users/mattbright/Desktop/SCripts/lattice_geo.py", line 6, in <module>
ax = plt.axes(projection=ccrs.Mollweide())
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/matplotlib/pyplot.py", line 947, in axes
return subplot(111, **kwargs)
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/matplotlib/pyplot.py", line 1125, in subplot
ax = fig.add_subplot(*args, **kwargs)
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/matplotlib/figure.py", line 1402, in add_subplot
ax = subplot_class_factory(projection_class)(self, *args, **kwargs)
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/matplotlib/axes/_subplots.py", line 42, in __init__
self._axes_class.__init__(self, fig, self.figbox, **kwargs)
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/cartopy/mpl/geoaxes.py", line 355, in __init__
super(GeoAxes, self).__init__(*args, **kwargs)
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/matplotlib/axes/_base.py", line 511, in __init__
self.cla()
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/cartopy/mpl/geoaxes.py", line 528, in cla
self._boundary()
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/cartopy/mpl/geoaxes.py", line 1425, in _boundary
trans_path = proj_to_data.transform_path(path)
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/matplotlib/transforms.py", line 1527, in transform_path
return self.transform_path_affine(self.transform_path_non_affine(path))
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/cartopy/mpl/geoaxes.py", line 181, in transform_path_non_affine
src_path.vertices, self.source_projection)
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/cartopy/crs.py", line 649, in quick_vertices_transform
if (x.min() >= x_limits[0] and x.max() <= x_limits[1] and
File "/Users/mattbright/opt/miniconda3/lib/python3.7/site-packages/numpy/core/_methods.py", line 43, in _amin
return umr_minimum(a, axis, None, out, keepdims, initial, where)
ValueError: zero-size array to reduction operation minimum which has no identity
I tried the installation with conda and with pip3 plus the list of dependencies given on the website.
There's one previous question about this issue which has gone unanswered since the questioner claimed that an Anaconda reinstall solved the problem. A similar issue with Seaborn has been raised here and solved by reverting to an earlier Matplotlib release (3.3.0)
None of these solutions have worked for me. Has anybody else encountered this and found a way to fix it?

Plotting densities with seaborn and latex error

I'm trying to plot densities graphs from some data, using seaborn.
It works fine without latex, but when I try to plot with latex, it gives me an error.
Here are the settings:
rcParams['text.usetex'] = True
rc('font',**{'family':'sans-serif','sans-serif':['Helvetica']})
rc('text', usetex=True)
plt.rcParams.update()
sns.set_context("paper")
sns.set(font_scale=1.5, rc={'text.usetex' : True})
sns.set_style('white', {'font.family':'serif', 'font.serif':'Times New Roman', 'background':'white'})
sns.despine()
and the graph is being plotted with:
sns.kdeplot(np.array(data), bw=0.4, cut=0)
plt.tight_layout(True)
plt.savefig('file.png', dpi=300)
Here is the error:
File "plotGraphs.py", line 214, in <module>
plotCarsReached()
File "plotGraphs.py", line 118, in plotCarsReached
plt.tight_layout(True)
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/pyplot.py", line 1337, in tight_layout
gcf().tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect)
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/cbook/deprecation.py", line 358, in wrapper
return func(*args, **kwargs)
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/figure.py", line 2491, in tight_layout
kwargs = get_tight_layout_figure(
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/tight_layout.py", line 355, in get_tight_layout_figure
kwargs = auto_adjust_subplotpars(fig, renderer,
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/tight_layout.py", line 109, in auto_adjust_subplotpars
tight_bbox_raw = union([ax.get_tightbbox(renderer) for ax in subplots
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/tight_layout.py", line 109, in <listcomp>
tight_bbox_raw = union([ax.get_tightbbox(renderer) for ax in subplots
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/axes/_base.py", line 4317, in get_tightbbox
bb_xaxis = self.xaxis.get_tightbbox(renderer)
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/axis.py", line 1197, in get_tightbbox
bboxes = [
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/axis.py", line 1198, in <genexpr>
*(a.get_window_extent(renderer)
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/text.py", line 905, in get_window_extent
bbox, info, descent = self._get_layout(self._renderer)
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/text.py", line 299, in _get_layout
w, h, d = renderer.get_text_width_height_descent(
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/backends/backend_agg.py", line 203, in get_text_width_height_descent
w, h, d = texmanager.get_text_width_height_descent(
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/texmanager.py", line 451, in get_text_width_height_descent
with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi:
File "/Users/iMac/.pyenv/versions/3.8.0/lib/python3.8/site-packages/matplotlib/dviread.py", line 198, in __init__
self.file = open(filename, 'rb')
FileNotFoundError: [Errno 2] No such file or directory: '/Users/iMac/.matplotlib/tex.cache/bff659c457d4aecfc8f90b11c18fa8b1.dvi'
If I remove the initial settings, the plot works.
Other plots using matplotlib instead of seaborn works as well.
Does anybody know how to fix this?
I had the same issue but was able to fix it. The issue is python is not finding latex and kpsewhich files. I resolved the issue by performing the following steps on a Mac and using PyCharm:
Install all recommended packages by Matplotlib latex
brew cask install mactex ghostscript
Manually add latex bin directory path to $PYTHONPATH at the begining in .bash_profile
export PYTHONPATH="/usr/local/texlive/2019/bin/x86_64darwin:/usr/local/bin:$PYTHONPATH"
Worked like a charm - the Matplotlib example output:
Text rendering With LaTeX
Hack to force PyCharm to update it's environment
In the "Run/Edit Configurations":
First uncheck "Add content roots to PYTHONPATH", run it, it will complain about something..
Then check it back on, and run again. This triggers some kind of update about the paths in the target environment
The error was appearing because I had a '%' in one of the axis labels, and I didn't change it to '\%' when I tried to plot it with latex..

Matplotlib latex error when using logarithmic axis scale, version-dependent

I get a latex error in matplotlib when running the following commands within python 2.7.15. It occurs when using a logarithmic axis scale. Whether the error appears or not depends on the matplotlib version, I tested with 1.5.1 (error does not occur) and 2.2.3 (error occurs). The error also only occurs when the code is executed within a single block (like in a function). See below for the minimal example (execute in two separate python consoles!). What exactly causes the error and how can I avoid it, while using the new matplotlib and tex mode?
Common code for both cases:
import sys
default_sys_path = sys.path
import numpy as np
def reproduce_error(old_matplotlib, outname):
if old_matplotlib == True:
sys.path = ['/opt/local/anaconda/anaconda-2.2.0/lib/python2.7/site-packages'] + default_sys_path
else:
sys.path = ['/scratch/seismo/proxauf/conda/lib/python2.7/site-packages'] + default_sys_path
import matplotlib
import matplotlib.pyplot as plt
print matplotlib.__version__
print matplotlib.__path__
plt.rcParams['text.usetex'] = True
plt.semilogy(np.arange(1,10)*10**(-10))
plt.savefig('/home/proxauf/%s' % outname)
plt.close()
plt.rcParams['text.usetex'] = False
Case 1 code and output (matplotlib 1.5.1):
reproduce_error(old_matplotlib=True, outname='test_mathdefault_old.pdf')
1.5.1
['/opt/local/anaconda/anaconda-2.2.0/lib/python2.7/site-packages/matplotlib']
Case 2 code and output (matplotlib 2.2.3):
reproduce_error(old_matplotlib=False, outname='test_mathdefault_new.pdf')
2.2.3
['/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib']
Traceback (most recent call last):
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/backends/backend_qt5.py", line 519, in _draw_idle
self.draw()
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/backends/backend_agg.py", line 437, in draw
self.figure.draw(self.renderer)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/figure.py", line 1493, in draw
renderer, self, artists, self.suppressComposite)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/image.py", line 141, in _draw_list_compositing_images
a.draw(renderer)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/axes/_base.py", line 2635, in draw
mimage._draw_list_compositing_images(renderer, self, artists)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/image.py", line 141, in _draw_list_compositing_images
a.draw(renderer)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/artist.py", line 55, in draw_wrapper
return draw(artist, renderer, *args, **kwargs)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/axis.py", line 1192, in draw
renderer)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/axis.py", line 1130, in _get_tick_bboxes
extent = tick.label1.get_window_extent(renderer)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/text.py", line 922, in get_window_extent
bbox, info, descent = self._get_layout(self._renderer)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/text.py", line 309, in _get_layout
ismath=ismath)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/backends/backend_agg.py", line 236, in get_text_width_height_descent
s, fontsize, renderer=self)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/texmanager.py", line 501, in get_text_width_height_descent
dvifile = self.make_dvi(tex, fontsize)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/texmanager.py", line 365, in make_dvi
texfile], tex)
File "/scratch/seismo/proxauf/conda/lib/python2.7/site-packages/matplotlib/texmanager.py", line 344, in _run_checked_subprocess
exc=exc.output.decode('utf-8')))
RuntimeError: latex was not able to process the following string:
'$\\\\mathdefault{10^{-10}}$'
Here is the full report generated by latex:
This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013/TeX Live for SUSE Linux)
restricted \write18 enabled.
entering extended mode
(/home/proxauf/.cache/matplotlib/tex.cache/be547c40948f52354492209662050ad0.tex
LaTeX2e <2011/06/27>
Babel <3.9f> and hyphenation patterns for 78 languages loaded.
(/usr/share/texmf/tex/latex/base/article.cls
Document Class: article 2007/10/19 v1.4h Standard LaTeX document class
(/usr/share/texmf/tex/latex/base/size10.clo))
(/usr/share/texmf/tex/latex/type1cm/type1cm.sty)
(/usr/share/texmf/tex/latex/base/textcomp.sty
(/usr/share/texmf/tex/latex/base/ts1enc.def))
(/usr/share/texmf/tex/latex/geometry/geometry.sty
(/usr/share/texmf/tex/latex/graphics/keyval.sty)
(/usr/share/texmf/tex/generic/oberdiek/ifpdf.sty)
(/usr/share/texmf/tex/generic/oberdiek/ifvtex.sty)
(/usr/share/texmf/tex/generic/ifxetex/ifxetex.sty)
Package geometry Warning: Over-specification in `h'-direction.
`width' (5058.9pt) is ignored.
Package geometry Warning: Over-specification in `v'-direction.
`height' (5058.9pt) is ignored.
) (./be547c40948f52354492209662050ad0.aux)
(/usr/share/texmf/tex/latex/base/ts1cmr.fd)
*geometry* driver: auto-detecting
*geometry* detected driver: dvips
! Undefined control sequence.
<recently read> \mathdefault
l.13 ...000000}{12.500000}{\sffamily $\mathdefault
{10^{-10}}$}
No pages of output.
Transcript written on be547c40948f52354492209662050ad0.log.
From that I understand the error is because of command \mathdefault. It is a command defined in the python, and no is a base command of Latex. Thus, to solve this problem, you need put above of plt.semilogy(np.arange(1,10)*10**(-10)) the below commands:
from matplotlib import rcParams
rcParams['text.latex.preamble'] = r'\newcommand{\mathdefault}[1][]{}'
Thereby,the command \mathdefault will be defined and will do nothing.
I rewrote you code with those suggestions,
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['text.usetex'] = True
rcParams['text.latex.preamble'] = r'\newcommand{\mathdefault}[1][]{}'
plt.semilogy(np.arange(1,10)*10**(-10))
# plt.savefig('/home/proxauf/%s' % outname) ## outname????
plt.close()
rcParams['text.usetex'] = False

Running a python script with cron, matplotlib error

I am trying to run a python script using cron. The script runs without issue from the command line but has problems with matplotlib when run from cron. The error is below.
Traceback (most recent call last):
File "/home/ubuntu/python/spread.py", line 154, in <module>
plot_spread(lat, lon, vals, mean, maxs, mins, stdp, stdm, ens_members)
File "/home/ubuntu/python/spread.py", line 81, in plot_spread
plt.fill_between(x, maxs, stdp, color='r', alpha=0.2)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/pyplot.py", line 2785, in fill_between
ax = gca()
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/pyplot.py", line 928, in gca
return gcf().gca(**kwargs)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/pyplot.py", line 578, in gcf
return figure()
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/pyplot.py", line 527, in figure
**kwargs)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4agg.py", line 46, in new_figure_manager
return new_figure_manager_given_figure(num, thisFig)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4agg.py", line 53, in new_figure_manager_given_figure
canvas = FigureCanvasQTAgg(figure)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4agg.py", line 76, in __init__
FigureCanvasQT.__init__(self, figure)
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt4.py", line 68, in __init__
_create_qApp()
File "/usr/lib/python2.7/dist-packages/matplotlib-1.5.0_818.gfd83789-py2.7-linux-x86_64.egg/matplotlib/backends/backend_qt5.py", line 138, in _create_qApp
raise RuntimeError('Invalid DISPLAY variable')
RuntimeError: Invalid DISPLAY variable
I got a similar error when I tried to import matplotlib.pyplot in python using cron. You can force matplotlib to not use any Xwindows backend. Do this:
import matplotlib as mpl
mpl.use('Agg')
import matplotlib.pyplot as plt
These links might be also helpful:
Generating a PNG with matplotlib when DISPLAY is undefined
Generating matplotlib graphs without a running X server
Hope this is helpful!

Mathtext markers in matplotlib

As I need to plot many curves in a single figure, I need many different types of markers. Sometimes the number of the default markers are not enough, so it would be nice if the user could customize the marker types.
According to the document page (http://matplotlib.sourceforge.net/api/artist_api.html#matplotlib.lines.Line2D.set_marker), it is possible to use mathtext as the marker. However, it did not work in my case.
plot(x, y, marker='$||$') # To use two vertical lines as the marker.
The error message is like this:
File "/usr/lib/pymodules/python2.6/matplotlib/axes.py", line 3432, in plot
for line in self._get_lines(*args, **kwargs):
File "/usr/lib/pymodules/python2.6/matplotlib/axes.py", line 311, in _grab_next_args
for seg in self._plot_args(remaining, kwargs):
File "/usr/lib/pymodules/python2.6/matplotlib/axes.py", line 298, in _plot_args
seg = func(x[:,j%ncx], y[:,j%ncy], kw, kwargs)
File "/usr/lib/pymodules/python2.6/matplotlib/axes.py", line 248, in _makeline
self.set_lineprops(seg, **kwargs)
File "/usr/lib/pymodules/python2.6/matplotlib/axes.py", line 191, in set_lineprops
func(val)
File "/usr/lib/pymodules/python2.6/matplotlib/lines.py", line 804, in set_marker
self._markerFunc = self._markers[marker]
KeyError: '$||$'
The matplotlib version is:
matplotlib.__version__
'0.99.1.1'
I also tried plot(x, y, marker=r'$||$'), which does not work either.
Have you set text.usetex in your matplotrc file? You also need to use the right output backend, such as Postscript or PDF.

Categories

Resources