Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Drawing dynamically n plots

I am writing measurement program and matplotlib is used to display measurement values as they are obtained. I figured out how to do that for single plot, i.e.

x=[0,1,2]
y=[3,5,7]
set_xdata(x)
set_ydata(y)

Each time x and y change, I call set_xdata and set_ydata and refresh graph.

However, I want to plot dynamically n y values against single x value, i.e.

x=[0,1,2]
y=[[3,5,7],[4,6,8],[5,7,9]]

Is that possible to do that, knowing n (number of y plots)?

EDIT:

I am interested in two things:

  1. How to just refresh data of multiplot instead of completely redrawing plot each time data change?
  2. Does matplotlib support multiple Y data against single X data plotting?
like image 486
Pygmalion Avatar asked May 02 '26 14:05

Pygmalion


1 Answers

In a nutshell: you have to create a Line2D instance for each "plot". And slightly more elaborative:

  1. As you have done it with a single line, you can also do the same with multiple lines:

    import matplotlib.pyplot as plt
    
    # initial values
    x = [0,1,2]
    y = [[3,5,7],[4,6,8],[5,7,9]]
    
    # create the line instances and store them in a list
    line_objects = list()
    for yi in y:
        line_objects.extend(plt.plot(x, yi))
    
    # new values with which we want to update the plot
    x = [1,2,3]
    y = [[4,6,8],[5,7,9],[6,8,0]]
    
    # update the y values dynamically (without recreating the plot)        
    for yi, line_object in zip(y, line_objects):
        line_object.set_xdata(x)
        line_object.set_ydata(yi)
    
  2. Not really. However, you can create mulitple Line2D objects by a single call to plot:

    line_objects = plt.plot(x, y[0], x, y[1], x, y[2])
    

    That is also why plot always returns a list.

EDIT:

If you have to do this often, it might help to use helper functions:

E.g.:

def plot_multi_y(x, ys, ax=None, **kwargs):
    if ax is None:
        ax = plt.gca()
    return [ax.plot(x, y, **kwargs)[0] for y in ys]

def update_multi_y(line_objects, x, ys):
    for y, line_object in zip(ys, line_objects):
        line_object.set_xdata(x)
        line_object.set_ydata(y)

Then you can just use:

# create the lines
line_objects = plot_multi_y(x, y)

#update the lines
update_multi_y(line_objects, x, y)
like image 64
hitzg Avatar answered May 04 '26 15:05

hitzg