TheCodeNovice
TheCodeNovice

Reputation: 771

Unable to Delete and redraw or Draw over plot axes based on PYQT widget state change

I am trying to make a dynamic chart where the patches are updated when the user moves a slider. I am using the matplotlib and pyqt packages that came with anaconda python. The code i have runs and does the drawing properly once but when I move the slider the update fails.

I have the following

my layout is created with the following class

class plotArea(QtGui.QWidget):

def __init__(self):
    super(plotArea, self).__init__()
    self.init()

def init(self):
    grid = QtGui.QGridLayout()
    self.setLayout(grid)
    title = QtGui.QLabel('Title')
    sldTime = QtGui.QSlider(QtCore.Qt.Horizontal)
    sldLevel = QtGui.QSlider(QtCore.Qt.Vertical)
    plot = MyDynamicMplCanvas()
    sldTime.valueChanged[int].connect(plot.changeValue)
    sldLevel.valueChanged[int].connect(plot.changeValue)
    grid.addWidget(title, 0, 0, 1, 10)
    grid.addWidget(sldLevel, 1, 0, 10, 1)
    grid.addWidget(sldTime, 11, 1, 1, 9)
    grid.addWidget(plot, 1, 1, 9, 9)

my chart class with the drawing and update method are shown below

class MyDynamicMplCanvas(FigureCanvas):

"""A canvas that updates itself every second with a new plot."""
def __init__(self):
    fig = Figure()
    FigureCanvas.__init__(self, fig)
    chart = fig.add_subplot(111)
    chart.set_xlim([0, 4])
    chart.set_ylim([0, 4])
    self.draw_lattice(chart)

def draw_lattice(self, chart):

    min_val = 0
    max_val = 100
    my_cmap = cm.get_cmap('jet')
    norm = matplotlib.colors.Normalize(min_val, max_val)
    color_i = my_cmap(norm(np.random.uniform(0, 100)))
    my_cmap = cm.get_cmap('jet')
    square = Rectangle((1, 1), 1, 1, alpha=0.5, facecolor=color_i,
    edgecolor='k')
    chart.add_patch(square)

    def changeValue(self,chart):
        self.draw_lattice(chart)

Since both methods are in the same class there shouldnt be any scoping issues and the code does work on the initial pass but gives the following error if I move the slider.

  chart.add_patch(square)

AttributeError: 'int' object has no attribute 'add_patch'

I have been struggling with this for a bit what am i doing wrong? Do I need to delete the subplot? I am not sure why calling from changeValue causes the code to fail. Any help is much appreciated.

Upvotes: 1

Views: 579

Answers (1)

Ajean
Ajean

Reputation: 5659

Even though you define chart in the init method, you don't actually keep a reference to it. To actually keep it you need to turn the line

chart = fig.add_subplot(111)

to

self.chart = fig.add_subplot(111)

then reference it using self.chart.

You are passing an integer into your slot, which will be the chart argument when the signal is generated, which is why you get that int error - chart is treated as an Axes object in the code, but any events will put an integer into that variable. I would change the input to your slot to be the slidervalue, and just reference self.chart to update your plot.

Upvotes: 1

Related Questions