1

Is it possible for matplotlib only update the newest point to the figure instead of re-draw the whole figure?

For example: this may be the fastest way for dynamic plotting

initiate:
fig1 = Figure(figsize = (8.0,8.0),dpi = 100)
axes1 = fig1.add_subplot(111)
line1, = axes1.plot([],[],animated = True)

when new data is coming:
line1.set_data(new_xarray,new_yarray)
axes1.draw_artist(line1)
fig1.canvas.update()
fig1.canvas.flush_events()

But this will re-draw the whole figure! I'm think whether this is possible:

when new data is coming:
axes1.draw_only_last_point(new_x,new_y)
update_the_canvas()

It will only add this new point(new_x,new_y) to the axes instead of re-draw every point.

And if you know which graphic library for python can do that, please answer or comment, thank you so much!!!!!

Really appreciate your help!

Matthew Woo
  • 1,288
  • 15
  • 28
disccip
  • 573
  • 3
  • 5
  • 15

2 Answers2

0

Is only redrawing the entire figure the problem, i.e. it is ok to redraw the line itself as long as the figure is unchanged? Is the data known beforehand?

If the answer to those questions are NO, and YES, then it might be worth looking into the animate-class for matplotlib. One example where the data is known beforehand, but the points are plotted one by one is this example. In the example, the figure is redrawn if the newest point is outside of the current x-lim. If you know the range of your data you can avoid it by setting the limits beforehand.

You might also want to look into this answer, the animate example list or the animate documentation.

Community
  • 1
  • 1
pathoren
  • 1,634
  • 2
  • 14
  • 22
  • Thank you. But animate-class is not working for my situation, since I use PyQtSlot and signal in PyQt4, which is not iterable. And from the code you can see that animate class actually re-draw the whole line. – disccip Aug 03 '16 at 17:26
  • Another solution might be to make a new line with just one point, and then use draw_artist with that point only. I do not know if this works the way you want and youll get a lot of lines if you have very many points and it might slow down your plotting. – pathoren Aug 03 '16 at 18:35
  • Great idea! I will try that to see whether it works for my situation. Thanks. – disccip Aug 03 '16 at 19:02
  • Good! Let me know about the outcome and I edit my answer. – pathoren Aug 03 '16 at 19:59
0

this is my (so far) little experience.
I started some month ago with Python(2.x) and openCV (2.4.13) as graphic library.I found in may first project that openCV for python works with numpy structure as much as matplotlib and (with slight difference) they can work together.

I had to update some pixel after some condition. I first did my elaboration from images with opencv obtaining a numpy 2D array, like a matrix. The trick is: opencv mainly thinks about input as images, in terms of X as width first, then Y as height. The numpy structure wants rows and columns wich in fact is Y before X.

With this in mind I updated pixel by pixel the image-matrix A and plot it again with a colormap

import matplotlib as plt
import cv2
A = cv2.imread('your_image.png',0) # 0 means grayscale
# now you loaded an image in a numpy array A
for every new x,y pixel
A[y,x] = new pixel intensity value
plot = plt.imshow(A, 'CMRmap')
plt.show()

If you want images again, consider use this

import matplotlib.image as mpimg
#previous code
mpimg.imsave("newA.png", A)

If you want to work with colors remember that images in colour are X by Y by 3 numpy array but matplotlib has RGB as the right order of channels, openCv works with BGR order. So

C = cv2.imread('colour_reference.png',1) # 1 means BGR
A[y,x,0] = newRedvalue = C[y,x][2]
A[y,x,1] = newGreenvalue = C[y,x][1]
A[y,x,2] = newBluevalue = C[y,x][0]

I hope this will help you in some way

marcoresk
  • 1,837
  • 2
  • 17
  • 29