0

I want to achieve the following: enter image description here

Here, the blue line must be the live streaming data obtained from a sensor (the above plot is of the stored dataset, not the live streaming). I'm trying to find the anomaly in the sensor data and show it along with the live data. The following code snippet yields a plot of live streaming data (the code snippet uses generated data).

import matplotlib.pyplot as plt
import numpy as np

# use ggplot style for more sophisticated visuals
plt.style.use('ggplot')

def live_plotter(x_vec,y1_data,line1,identifier='',pause_time=0.1):
    if line1==[]:
        # this is the call to matplotlib that allows dynamic plotting
        plt.ion()
        fig = plt.figure(figsize=(13,6))
        ax = fig.add_subplot(111)
        # create a variable for the line so we can later update it
        line1, = ax.plot(x_vec,y1_data,'-o',alpha=0.8)        
        #update plot label/title
        plt.ylabel('Y Label')
        plt.title('Title: {}'.format(identifier))
        plt.show()
    
    # after the figure, axis, and line are created, we only need to update the y-data
    line1.set_ydata(y1_data)
    # adjust limits if new data goes beyond bounds
    if np.min(y1_data)<=line1.axes.get_ylim()[0] or np.max(y1_data)>=line1.axes.get_ylim()[1]:
        plt.ylim([np.min(y1_data)-np.std(y1_data),np.max(y1_data)+np.std(y1_data)])
    # this pauses the data so the figure/axis can catch up - the amount of pause can be altered above
    plt.pause(pause_time)
    
    # return line so we can update it again in the next iteration
    return line1


size = 100
x_vec = np.linspace(0,1,size+1)[0:-1]

y_vec = np.random.randn(len(x_vec))

line1 = []
while True:
    rand_val = np.random.randn(1)
    y_vec[-1] = rand_val
    line1 = live_plotter(x_vec,y_vec,line1)
    y_vec = np.append(y_vec[1:],0.0)

I'm able to fetch the sensor's data to the above code (y_vec) and plot the live streaming graph. Meanwhile, the sensor's data is also fetched to a method that estimates anomalies in data and returns the anomaly scores (an array of scores). I want to plot these anomaly scores (the vertical red lines are the selected scores whose values are larger than a threshold) along with the live data.

How can I achieve it? Is there any other way to plot live streaming data with two y-values sharing a single x-value?

santobedi
  • 866
  • 3
  • 17
  • 39
  • 1
    if you want to plot another data set, `y2_data`, you can just make a second `ax.plot` call. Or am I misunderstanding your problem? – Jody Klymak Feb 04 '22 at 10:04
  • Hi @JodyKlymak, I'm trying to figure out a solution where I can plot two y-values in a single graph as explained [here](https://cmdlinetips.com/2019/10/how-to-make-a-plot-with-two-different-y-axis-in-python-with-matplotlib/#:~:text=The%20way%20to%20make%20a,by%20updating%20the%20axis%20object.) using `twinx()`. However, I need this graph to be live streaming both the y-values (a live graph). – santobedi Feb 04 '22 at 10:55
  • But it seems you don't need another axis, you want to add a [vline](https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.axvline.html) at x-values determined by your anomaly score. – Mr. T Feb 04 '22 at 11:03
  • Before doing a live graph, very strongly suggest you figure out how to make a static one. – Jody Klymak Feb 04 '22 at 12:15

0 Answers0