This may be related to #166, but has a quite different immediate cause, so I'm reporting it separately. It might be that I should instead report this in ipython, so feel free to redirect me there, if that's more appropriate
If I do the following in ipython started with ipython -pylab=MacOSX :
I get a CGContextRef is NULL exception (full traceback in the first comment). The plot still appears, but it does not have the tight-layout applied. If I change the function instead to:
Currently, tight_layout makes the layout tight but does not maintain tightness. So if I call tight_layout but then add a label to an axis or resize the figure, the layout will not be tight anymore (it will be either too tight or not tight enough). Is this how it is supposed to function?
Currently, tight_layout makes the layout tight but does not maintain tightness. So if I call tight_layout but then add a label to an axis or resize the figure, the layout will not be tight anymore (it will be either too tight or not tight enough). Is this how it is supposed to function?
Btw the comment above is relevant for this bug. Depending on how tight_layout is supposed to function, the offending code may need to move to figure.draw. If so, it would be called from inside the event loop, and this bug would go away.
My understanding has been that this is meant to be a one-shot function, to
be used prior to show() and/or savefig(). A couple years ago, I did put up
a PR for adding a tight_layout() button that could be used in interactive
mode, but it didn't gather enough interest at that time. Of course,
tight_layout() was much less mature at that time, so maybe it is time to
revisit that decision?
If tight_layout is redesigned, I'd be happy to help out in making sure that this bug doesn't reappear. This shouldn't be too hard: As long as the renderer is only used from inside the event loop callback (i.e., somewhere within the call to figure.draw), everything should be OK. The current tight_layout code on the other hand uses the renderer outside of figure.draw, which is causing this bug.
Having the same problem here myself. Does anyone have any recommendations for alternative backends in OSX? PyQT is giving me some speed problems with ipython (ipython -pylab=qt) with:
@ribonoous - I've generally used Tk when having problems with the other backends - it seems to nearly always work at least ok.
Another option for the specific problem here is to do gcf().set_tight_layout(True) before plotting. For me that worked, even though the pylab.tight_layout call gave the error here.
a temporary solution
Do not include tight_layout in your script/code.
After plotting it, use tight_layout on terminal before/after showing it if you want. Then save it.
I just add plt.show() before tight_layout() as below. And it works for me.
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
sns.set(style="dark")
rs = np.random.RandomState(50)
# Set up the matplotlib figure
f, axes = plt.subplots(3, 3, figsize=(9, 9), sharex=True, sharey=True)
# Rotate the starting point around the cubehelix hue circle
for ax, s in zip(axes.flat, np.linspace(0, 3, 10)):
# Create a cubehelix colormap to use with kdeplot
cmap = sns.cubehelix_palette(start=s, light=1, as_cmap=True)
# Generate and plot a random bivariate dataset
x, y = rs.randn(2, 50)
sns.kdeplot(x, y, cmap=cmap, shade=True, cut=5, ax=ax)
ax.set(xlim=(-3, 3), ylim=(-3, 3))
plt.show() # I just add this line, and it works
f.tight_layout()
Activity
eteq commented on Dec 5, 2013
Traceback:
--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-3-b0df2d66a819> in <module>() ----> 1 dp(randn(10)) <ipython-input-2-a2aa5ad11bf1> in dp(x) 3 plot(x) 4 #draw() ----> 5 tight_layout() 6 /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/pyplot.pyc in tight_layout(pad, h_pad, w_pad, rect) 1253 1254 fig = gcf() -> 1255 fig.tight_layout(pad=pad, h_pad=h_pad, w_pad=w_pad, rect=rect) 1256 draw_if_interactive() 1257 /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/figure.pyc in tight_layout(self, renderer, pad, h_pad, w_pad, rect) 1603 renderer, 1604 pad=pad, h_pad=h_pad, w_pad=w_pad, -> 1605 rect=rect) 1606 1607 self.subplots_adjust(**kwargs) /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/tight_layout.pyc in get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, pad, h_pad, w_pad, rect) 350 subplot_list=subplot_list, 351 ax_bbox_list=ax_bbox_list, --> 352 pad=pad, h_pad=h_pad, w_pad=w_pad) 353 354 if rect is not None: /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/tight_layout.pyc in auto_adjust_subplotpars(fig, renderer, nrows_ncols, num1num2_list, subplot_list, ax_bbox_list, pad, h_pad, w_pad, rect) 127 #ax_bbox = union([ax.get_position(original=True) for ax in subplots]) 128 --> 129 tight_bbox_raw = union([ax.get_tightbbox(renderer) for ax in subplots]) 130 tight_bbox = TransformedBbox(tight_bbox_raw, 131 fig.transFigure.inverted()) /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axes.pyc in get_tightbbox(self, renderer, call_axes_locator) 9155 bb.append(self._right_title.get_window_extent(renderer)) 9156 -> 9157 bb_xaxis = self.xaxis.get_tightbbox(renderer) 9158 if bb_xaxis: 9159 bb.append(bb_xaxis) /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axis.pyc in get_tightbbox(self, renderer) 1053 ticks_to_draw = self._update_ticks(renderer) 1054 ticklabelBoxes, ticklabelBoxes2 = self._get_tick_bboxes(ticks_to_draw, -> 1055 renderer) 1056 1057 self._update_label_position(ticklabelBoxes, ticklabelBoxes2) /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/axis.pyc in _get_tick_bboxes(self, ticks, renderer) 1036 for tick in ticks: 1037 if tick.label1On and tick.label1.get_visible(): -> 1038 extent = tick.label1.get_window_extent(renderer) 1039 ticklabelBoxes.append(extent) 1040 if tick.label2On and tick.label2.get_visible(): /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/text.pyc in get_window_extent(self, renderer, dpi) 751 raise RuntimeError('Cannot get window extent w/o renderer') 752 --> 753 bbox, info, descent = self._get_layout(self._renderer) 754 x, y = self.get_position() 755 x, y = self.get_transform().transform_point((x, y)) /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/text.pyc in _get_layout(self, renderer) 318 tmp, lp_h, lp_bl = get_text_width_height_descent('lp', 319 self._fontproperties, --> 320 ismath=False) 321 offsety = (lp_h - lp_bl) * self._linespacing 322 /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/matplotlib/backends/backend_macosx.pyc in get_text_width_height_descent(self, s, prop, ismath) 156 points = prop.get_size_in_points() 157 size = self.points_to_pixels(points) --> 158 width, height, descent = self.gc.get_text_width_height_descent(unicode(s), family, size, weight, style) 159 return width, height, 0.0*descent 160 RuntimeError: CGContextRef is NULLmdboom commented on Dec 5, 2013
Cc: @mdehoon
mdehoon commented on Dec 9, 2013
Currently, tight_layout makes the layout tight but does not maintain tightness. So if I call tight_layout but then add a label to an axis or resize the figure, the layout will not be tight anymore (it will be either too tight or not tight enough). Is this how it is supposed to function?
mdehoon commented on Dec 9, 2013
Currently, tight_layout makes the layout tight but does not maintain tightness. So if I call tight_layout but then add a label to an axis or resize the figure, the layout will not be tight anymore (it will be either too tight or not tight enough). Is this how it is supposed to function?
mdehoon commented on Dec 9, 2013
Btw the comment above is relevant for this bug. Depending on how tight_layout is supposed to function, the offending code may need to move to figure.draw. If so, it would be called from inside the event loop, and this bug would go away.
WeatherGod commented on Dec 9, 2013
My understanding has been that this is meant to be a one-shot function, to
be used prior to show() and/or savefig(). A couple years ago, I did put up
a PR for adding a tight_layout() button that could be used in interactive
mode, but it didn't gather enough interest at that time. Of course,
tight_layout() was much less mature at that time, so maybe it is time to
revisit that decision?
mdehoon commented on Dec 10, 2013
If tight_layout is redesigned, I'd be happy to help out in making sure that this bug doesn't reappear. This shouldn't be too hard: As long as the renderer is only used from inside the event loop callback (i.e., somewhere within the call to figure.draw), everything should be OK. The current tight_layout code on the other hand uses the renderer outside of figure.draw, which is causing this bug.
amelio-vazquez-reina commented on Feb 12, 2014
Having the same problem here myself. Does anyone have any recommendations for alternative backends in OSX? PyQT is giving me some speed problems with ipython (ipython -pylab=qt) with:
In case it matters, I am using conda.
Thanks,
Josh
eteq commented on Feb 12, 2014
@ribonoous - I've generally used Tk when having problems with the other backends - it seems to nearly always work at least ok.
Another option for the specific problem here is to do gcf().set_tight_layout(True) before plotting. For me that worked, even though the pylab.tight_layout call gave the error here.
tacaswell commented on Feb 25, 2014
Tagging this as 1.5.x as this seems to involve a major re-write. Please re-milestone if I am wrong.
Change tight_layout commands to avoid errors on Mac OSX
absimaHere commented on Oct 27, 2014
a temporary solution
Do not include tight_layout in your script/code.
After plotting it, use tight_layout on terminal before/after showing it if you want. Then save it.
huangshiyu13 commented on Mar 25, 2017
I just add plt.show() before tight_layout() as below. And it works for me.
import numpy as np import seaborn as sns import matplotlib.pyplot as plt sns.set(style="dark") rs = np.random.RandomState(50) # Set up the matplotlib figure f, axes = plt.subplots(3, 3, figsize=(9, 9), sharex=True, sharey=True) # Rotate the starting point around the cubehelix hue circle for ax, s in zip(axes.flat, np.linspace(0, 3, 10)): # Create a cubehelix colormap to use with kdeplot cmap = sns.cubehelix_palette(start=s, light=1, as_cmap=True) # Generate and plot a random bivariate dataset x, y = rs.randn(2, 50) sns.kdeplot(x, y, cmap=cmap, shade=True, cut=5, ax=ax) ax.set(xlim=(-3, 3), ylim=(-3, 3)) plt.show() # I just add this line, and it works f.tight_layout()