Search code examples
pythonmatplotlibmatplotlib-animation

Append data with different colour in matplotlib in real time


I'm updating dynamically a plot in a loop:

dat=[0, max(X[:, 0])]
fig = plt.figure()
ax = fig.add_subplot(111)
Ln, = ax.plot(dat)
Ln2, = ax.plot(dat)

plt.ion()
plt.show() 
for i in range(1, 40):
            ax.set_xlim(int(len(X[:i])*0.8), len(X[:i])) #show last 20% data of X
            Ln.set_ydata(X[:i])
            Ln.set_xdata(range(len(X[:i])))
            
            Ln2.set_ydata(Y[:i])
            Ln2.set_xdata(range(len(Y[:i])))
            
            plt.pause(0.1)

But now I want to update it in a different way: append some values and show them in other colour:

X.append(other_data)
# change colour just to other_data in X

The result should look something like this:

final plot

How could I do that?


Solution

  • Have a look at the link I posted. Linesegments can be used to plot colors at a particular location differently. If you want to do it in real-time you can still use line-segments. I leave that up to you.

    enter image description here

    # adjust from https://stackoverflow.com/questions/38051922/how-to-get-differents-colors-in-a-single-line-in-a-matplotlib-figure
    import numpy as np, matplotlib.pyplot as plt
    from matplotlib.collections import LineCollection
    from matplotlib.colors import ListedColormap, BoundaryNorm
    
    # my func
    x = np.linspace(-2 * np.pi, 2 * np.pi, 100)
    y = 3000 * np.sin(x)
    
    # select how to color
    cmap = ListedColormap(['r','b'])
    norm = BoundaryNorm([2000,], cmap.N)
    
    # get segments
    xy = np.array([x, y]).T.reshape(-1, 1, 2)
    segments = np.hstack([xy[:-1], xy[1:]])
    
    # control which values have which colors
    n = y.shape[0]
    c = np.array([plt.cm.RdBu(0) if i < n//2 else plt.cm.RdBu(255) for i in range(n)])
    # c = plt.cm.Reds(np.arange(0, n))
    
    
    # make line collection
    lc = LineCollection(segments, 
                        colors = c
    #                     norm = norm,
                   )
    # plot
    fig, ax = plt.subplots()
    ax.add_collection(lc)
    ax.autoscale()
    ax.axvline(x[n//2], linestyle = 'dashed')
    
    ax.annotate("Half-point", (x[n//2], y[n//2]), xytext = (4, 1000),
       arrowprops = dict(headwidth = 30))
    fig.show()