pythonqtmatplotlibpyqtqt-designer

Plot a figure on a canvas


I am using Qt Designer and matplotlib for plotting.

So far, I've promoted a Qwidget to a Canvas class and draw my plots on it by creating axes and plotting them with figure.add_subplot(), so code looks this way:

ax = self.canvas.figure.add_subplot(111)

ax.plot(data)

self.canvas.draw()

But now I have a figure object and I need to plot it. Is there a way to do that without instanciating axes and assigning them to a figure? Is there a way I can do : "self.canvas.add_figure" ? Because in my case I don't have access to the axes.

Edit : here's the code of the canvas.

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas 
import matplotlib.pyplot as plt
from PyQt4 import QtGui
class Canvas(FigureCanvas):
    def __init__(self, parent=None):
        self.figure = plt.figure()
        FigureCanvas.__init__(self, self.figure)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self,
                               QtGui.QSizePolicy.Expanding,
                               QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

Solution

  • The problem may be due to wrong assumtions: If you have a figure and that figure contains one or more axes, you can access the axes via fig.get_axes(). If the figure does not contain axes, you can still add axes to it via fig.add_subplot() or fig.add_axes(). So the problem you are trying to solve here, might be easily circumvented.

    Coming to the question itself. A canvas is always associated with a figure. A canvas without figure makes no sense. There are two options:

    1. Create the canvas with the available figure

    You may delay the creation of the FigureCanvas until you have access to the figure you want to show.

    self.figure = <figure you want to show>
    FigureCanvas.__init__(self, self.figure)
    

    2. Replace the canvas

    You may replace the canvas you already have with a canvas that hosts the new figure to show.

    self.layout().removeWidget(self.canvas)
    # create a new canvas
    self.figure = <figure you want to show>
    self.canvas = FigureCanvas(self.figure)
    # add the new canvas at the position of the old one
    self.layout().addWidget(self.canvas, 1)
    self.canvas.draw()
    self.parent.parent.processEvents()