1

I have matplotlib embedded in a PyQt4 app that I'm working on. The problem is when I dynamically add a subplot to the figure, the figures compress with every added subplot. I thought I could solve this by setting the figure to a QScrollArea but that doesn't work (as far as I can tell). Here's an example of what I thought would work

import os
os.environ['QT_API'] = 'pyside'

from PySide.QtGui   import *
from PySide.QtCore  import *

import matplotlib

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
from matplotlib.figure                  import Figure


class Canvas(FigureCanvasQTAgg):

    def __init__(self, parent=None):
        self.figure = Figure()
        super(Canvas, self).__init__(self.figure)

        ax = self.figure.add_subplot(1,1,1)
        ax.plot([1,2,3])
        self.draw()

    def add_subplot(self, data=[]):
        rows = len(self.figure.axes) + 1
        for index, axes in enumerate(self.figure.axes, start=1):
            axes.change_geometry(rows, 1, index)

        ax = self.figure.add_subplot(rows, 1, index+1)
        ax.plot(data)

        self.draw()

class Main(QWidget):

    def __init__(self, parent=None):
        super(Main, self).__init__(parent)

        self.canvas = QScrollArea(self)
        self.canvas.setWidget(Canvas(self))
        self.canvas.setWidgetResizable(True)

        for x in range(5):
            self.canvas.widget().add_subplot()

        layout = QVBoxLayout(self)
        layout.addWidget(self.canvas)


app = QApplication([])
main = Main()
main.show()
app.exec_()

Notice how all the graphs are smashed together to show then in the same visible space? I wan't have to scroll to see the other graphs. I'm not sure how to do this exactly.

Anyone know how to do this or another way of doing this?

1 Answer 1

2

Two steps to sketch an idea to solve this:

Unset the resizing of the ScollArea to display scroll bars. Change the line:

self.canvas.setWidgetResizable(True)

to

self.canvas.setWidgetResizable(False)

Then when adding a subplot change the figure height, because the canvas will determine it's height by checking the size of the figure:

def add_subplot(self, data=[]):
    rows = len(self.figure.axes) + 1
    for index, axes in enumerate(self.figure.axes, start=1):
        axes.change_geometry(rows, 1, index)

    ax = self.figure.add_subplot(rows, 1, index+1)
    ax.plot(data)
    self.figure.set_figheight(self.figure.get_figheight()*1.25)
    self.draw()

In the Main you have to let PySide know, that the it has to resize the widget in the scroll area:

    for x in range(5):
        self.canvas.widget().add_subplot()
        self.canvas.widget().adjustSize()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.