Search code examples
matplotlibpyqt4embedding

PyQt4 and matplotlib: Legend outside of the plot is cut off


I've been googling a lot, but I haven't found a solution. The problem is the same as here: Moving matplotlib legend outside of the axis makes it cutoff by the figure box But I don't want to save the figure, I just want to have the legend inside the whole figure. I've also tried tight_layout but that didn't work. I'm totally new to matplotlib and can't figure it out. Here is my source code (I'm embedding a matplot into PyQt4):

class GraphACanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=5, dpi=100):        
        self.fig = Figure(figsize=(width, height), facecolor=backColorHexName, dpi=dpi)
        self.axes = self.fig.add_subplot(1, 1, 1, autoscale_on=False)

        self.axes.set_xticks(arange(-0.1, 1.4, 0.1))
        self.axes.set_yticks(arange(-0.1, 1.4, 0.1))

        FigureCanvas.__init__(self, self.fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, Gui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

def computeFigure(self):
    col = []
    for i in xrange(0, 100):
        x = i/100
        y = y/100
        line, = self.axes.plot(x, y, 'o', color=blue, label='label')
        col.append(line.get_c())

    self.axes.set_xlabel('x', labelpad=10, rotation=0)
    self.axes.set_ylabel('y', labelpad=10, rotation=0)

    leg = self.axes.legend(loc=2, bbox_to_anchor=(1.0, 0.5), borderaxespad=0., fontsize='x-small', framealpha=0.25, markerscale=0.5, ncol=1, numpoints=1)

    for color,text in zip(col,leg.get_texts()):
        text.set_color(color)

test = GraphACanvas()
test.computeFigure()

I've put in here just dummy values. But in the application, a user can select nodes, and depending on how many nodes he select, the bigger/smaller is the legend. I would like to shrink the x-axis side to have more place for the legend. --> The subplot should not fill out 100% (width/height) of the figure, rather 100% height and 80% width, so that my legend has enough space.


Solution

  • This line:

    self.axes = self.fig.add_subplot(1, 1, 1, autoscale_on=False)

    Will create an axes that fills out the whole figure (more or less) as you describe.

    Try:

    self.axes = self.fig.add_axes([0.1, 0.1, 0.7, 0.8])

    The elements for that list are:

    [left_edge, bottom_edge, width, height] where all values are fractions of the total figure dimensions.