Repository navigation
Closed as not planned
Labels
New featurekeepItems to be ignored by the “Stale” Github ActionItems to be ignored by the “Stale” Github Actiontopic: geometry managerLayoutEngine, Constrained layout, Tight layoutLayoutEngine, Constrained layout, Tight layouttopic: text
Milestone
Description
Hi.
I'm drawing a pie chart and the labels are cut off of the Figure. I thought this would be solved by tight_layout (as per this issue for instance) but this does not seem to be the case, at least for a pie chart.
Below is a code snippet to reproduce. In fact, tight_layout makes it even worse since it ignores the labels and crops tighter to the pie.
Is there a way around this ?
Am I doing things wrong ?
# -*- coding: utf-8 -*-
import sys
from PyQt4 import QtGui
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import (
FigureCanvasQTAgg as FigureCanvas)
class MplCanvas(FigureCanvas):
"""Class to represent the FigureCanvas widget"""
def __init__(self):
# Setup Matplotlib Figure and Axis
self.fig = Figure(facecolor="white")
self.axes = self.fig.add_subplot(111)
# Initialization of the canvas
super(MplCanvas, self).__init__(self.fig)
# Define the widget as expandable
FigureCanvas.setSizePolicy(self,
QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
# Notify the system of updated policy
FigureCanvas.updateGeometry(self)
# Call tight_layout on resize
#self.mpl_connect('resize_event', self.fig.tight_layout)
class MplWidget(QtGui.QWidget):
"""Widget defined in Qt Designer"""
def __init__(self, parent = None):
super(MplWidget, self).__init__(parent)
# Set canvas and navigation toolbar
self.canvas = MplCanvas()
# Layout as vertical box
self.vbl = QtGui.QVBoxLayout()
self.vbl.addWidget(self.canvas)
self.setLayout(self.vbl)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
W = MplWidget()
W.canvas.axes.cla()
values = [0.2, 0.5, 0.3]
labels = ['label',
'looooooog label',
'very loooooooooooooooooooooooog label'
]
W.canvas.axes.pie(values, labels=labels)
W.canvas.axes.axis('equal')
W.canvas.fig.tight_layout()
W.canvas.draw()
W.show()
sys.exit(app.exec_())I'm using python 2.7 and Matplotlib 1.4.3~rc1 from Debian experimental.
Metadata
Metadata
Assignees
Labels
New featurekeepItems to be ignored by the “Stale” Github ActionItems to be ignored by the “Stale” Github Actiontopic: geometry managerLayoutEngine, Constrained layout, Tight layoutLayoutEngine, Constrained layout, Tight layouttopic: text
Activity
tacaswell commentedon Mar 20, 2015
Minimal code to reproduce:
It is easier for use if your examples use the pyplot interface for managing the figure/axes as the details of the embedding should not matter.
This is an interesting pathological example. As I understand it
tight_layoutwas intended to deal with overlaps between axes and axes labels when there are multiple axes in the same figure. Normally Artists are clipped to an axes so alltight_layoutlooks at is the position (ex specified bounding box of the axes is figure fraction units). However in the case ofpiewe turn the axes and clipping of the text + wedges off by default so the assumption made intight_layoutis no longer true as the text may fall outside of axes and be visible.WeatherGod commentedon Mar 20, 2015
Yeah, tight_layout() is specifically designed for preventing overlaps of
subplots when laying them out. The minimal code to reproduce is actually
incorrect because it is only one subplot, and so tight_layout() really
wouldn't be doing much here (it'll do a bit of neatening up, but nothing
significant).
The feature you are (sort of) looking for is the
bbox_inches='tight'option to savefig(), but that is only available upon save. Maybe it is time
to consider bringing that out of savefig()?
On Fri, Mar 20, 2015 at 9:49 AM, Thomas A Caswell notifications@github.com
wrote:
WeatherGod commentedon Mar 20, 2015
I should note that Thomas's intuition is still correct. If there were
multiple subplots, I don't think tight_layout() would work properly since
it doesn't properly caclulate the bbox of each subplot.
On Fri, Mar 20, 2015 at 9:58 AM, Benjamin Root ben.root@ou.edu wrote:
tacaswell commentedon Mar 20, 2015
@WeatherGod It is still doing something here, because there are no tick labels it is expanding the one axes to have the bounding box
[0, 1, 0, 1](or as close to that as the aspect allows).WeatherGod commentedon Mar 20, 2015
Well, yeah, that's what it is supposed to do. However, it won't resize any
text objects if they aren't tick labels, axes labels, titles, or suptitles,
and I don't think I would want it to mess around with any other text
objects. If we do, we would have to be very careful about that.
Meanwhile, bbox_inches='tight' resizes the figure to accomodate all visible
artist objects, but won't mess around with anything else.
On Fri, Mar 20, 2015 at 10:08 AM, Thomas A Caswell <notifications@github.com
lafrech commentedon Mar 20, 2015
(Sorry about the snippet. I didn't figure out about pyplot. Thanks for writing the minimal example.)
These concepts are pretty new to me. I searched through the docs, but my understanding of the insides of Matplotlib is close to zero. However, I think WeatherGod is probably right about the parallel with the savefig() function, at least from a user perpective.
Ultimately, I'd like to copy the plot to the clipboard to insert it in a document. Currently, I can either
A modification to the savefig() function that would allow saving to clipboard would be a workaround for my use case. Of course, having the plot display correctly in the widget in the first place would be even better.
tacaswell commentedon Mar 20, 2015
You can save to a
StringIOobject which you can then (I assume?) shove in to the clipboard.The internals of mpl are militantly GUI/OS independent so getting clipboard functionality down into savefig may be difficult.
lafrech commentedon Mar 20, 2015
Right. I get the point (clipboard being GUI dependent, etc.). Thanks for the tip.
jklymak commentedon Mar 8, 2018
#10682 gets this example closer with
cosntrained_layout. But differences between the rendered and final fontsize mean I need to throw a few extrafig.canvas.draw()commands in there 👎github-actions commentedon Mar 11, 2023
This issue has been marked "inactive" because it has been 365 days since the last comment. If this issue is still present in recent Matplotlib releases, or the feature request is still wanted, please leave a comment and this label will be removed. If there are no updates in another 30 days, this issue will be automatically closed, but you are free to re-open or create a new issue if needed. We value issue reports, and this procedure is meant to help us resurface and prioritize issues that have not been addressed yet, not make them disappear. Thanks for your help!
jklymak commentedon Mar 11, 2023
This is still a problem, even if you don't use
ax.axis('equal'). The bounding box of the labels is not set until draw time. If you removeax.axis('equal')and throw afig.draw_without_renderingin there, it works OK.jklymak commentedon Mar 12, 2023
Actually I'll close this. This is a case where we don't know the extent of the text until it is draw at the correct location, which we don't know until after a draw. We already document that some cases require
fig.draw_without_rendering(), and this is one of them.