0

I am trying to plot two updating plots, one is a diagram and the other one is an image captured from the camera.

I get an error on this line:

"current_line.set_data(y_data)" in the "update" function.  
The error says: "AttributeError: 'list' object has no attribute 'set_data'".

Any idea why am I getting this error? If I comment out this line I will get changing images from the camera and everything except the second plot seems fine (because the second plot is not updating) but I need the second plot to be updated as well.

y_data = [0]
# Capture intial frame
ret, initial_frame = lsd.cap.read()

# Function for making the initial figure
def makeFigure():
    fig = plt.figure()

    # Show frame
    ax1 = plt.subplot2grid((2, 2), (0, 0), colspan=2)
    plot_frame = ax1.imshow(initial_frame, animated=True)

    # Set the limits of the plot and plot the graph
    ax2 = plt.subplot2grid((2, 2), (1, 0), colspan=2)
    ax2.set_title('Title')
    ax2.set_ylabel('Y-Label')
    ax2.set_ylim(0, 100)
    ax2.set_xlim(0, 100)
    ax2.grid()
    line = ax2.plot(y_data, 'o-')

    return fig, plot_frame, line

def update(i, current_frame, current_line, y_data):
    # Capture original frame_new_RGB from camera
    ret, frame_new_original = lsd.cap.read()

    # Changing frame_new_original's color order
    frame_new_RGB = cv2.cvtColor(frame_new_original, cv2.COLOR_BGRA2RGB)

    y_data.append(randint(0, 9))

    # Update figure
    current_line.set_data(y_data)

    # Update frame
    current_frame.set_data(frame_new_RGB)


# Make figures and animate the figures
curr_fig, curr_frame, curr_line = makeFigure()
anim = FuncAnimation(curr_fig, update, fargs=[curr_frame, curr_line, y_data], interval=10)

plt.show()

# When everything done, release the capture
lsd.cap.release()
cv2.destroyAllWindows()

UPDATED ISSUE:

The first problem is solved but now I am facing another one. My program freezes after running it and it does not generate any errors.There is another thing that might be relevant to this problem, I am multithreading and this piece of code is in the main thread.

Pedram
  • 97
  • 3
  • 14

1 Answers1

5

ax.plot returns a list of Line2D instances (in your case, its a 1-item list). This is because it is possible to plot multiple lines in one go with ax.plot.

So, in your case, you just need to grab the first item of the list. The simplest way is probably to change this line:

line = ax2.plot(y_data, 'o-')

to this:

line, = ax2.plot(y_data, 'o-')

Note that while your question is about setting the data of the line, rather than adding a legend, this Q&A are relevant here, since the solution is the same: Python legend attribute error

tmdavison
  • 64,360
  • 12
  • 187
  • 165
  • Actually, I tried that but my program just freezes after changing that so I thought it might not be the right thing to do... but now it seems the problem of freezing has another reason! do you have any idea why it is freezing while I run the code? It does not generate any errors, it just freezes! There is another thing that might be relevant to this problem. I am multithreading and this piece of code is in the main thread. – Pedram Jan 27 '18 at 09:43