Skip to content
Advertisement

How to plot scatter graph with SCATTER fill_between in Python?

I am a manufacturing engineer, very new to Python and Matplotlib. Currently, I am trying to plot a scatter time graph, where for every single record, I have the data (read from a sensor) and upper and lower limits for that data that will stop the tool if data is not between them.

So for a simple set of data like this:

   time = [1, 2, 3, 7, 8, 9, 10]*
   data = [5, 6, 5, 5, 6, 7, 8]
   lower_limit = [4, 4, 5, 5, 5, 5, 5]
   upper_limit = [6, 6, 6, 7, 7, 7, 7]
  • When the tool is not working, nothing will be recorded, hence a gap b/w 3 & 7 in time records.

The desired graph would look like this:

enter image description here

A few rules that I am trying to stick to:

  1. All three graphs (data, upper_limit, and lower_limit) are required to be scattered points and not lines, with the x-axis (time) being shared among them. – required.
  2. A green highlight that fills between upper and lower limits, considering only the two points with the same time for each highlight. – highly recommended. (I tried matplotlib.fill_between, but it creates a polygon between trend lines, rather than straight vertical lines between matching pairs of L.L. & U.L. dots. Therefore, it won’t be accurate, and it will fill up the gap b/w times 3s and 7s, which is not desired. Also, I tried to use matplot.bar for limits along the scatter plot for the ‘data’, but I was not able to set a minimum = lower_limit for the bars.)
  3. When the value of data is not equal to or between the limits, the representing dot should appear in red, rather than the original color. -highly recommended.

So, with all of that in mind, and thousands of records per day, a regular graph, for a 24hr time span, should look like the following: (notice the gap due to possible lack of records in a time span, as well as vertical green lines, for the limits.)

enter image description here

Thanks for your time and help!

Advertisement

Answer

This is a version using numpys masking and matplotlibs errorbar

import matplotlib.pyplot as plt
import numpy as np

time = np.array( [0, 1, 2, 3, 7, 8, 9, 10] )
data = np.array([2, 5, 6, 5, 5, 6, 7, 8] )
lower = np.array([4, 4, 4, 5, 5, 5, 5, 5] )
upper = np.array([6, 6, 6, 6, 7, 7, 7, 7] )

nn = len( lower )
delta = upper - lower

### creating masks
inside = ( ( upper - data ) >= 0 ) & ( ( data - lower ) >= 0 )
outside = np.logical_not( inside )


fig = plt.figure()
ax = fig.add_subplot( 1, 1, 1 )

ax.errorbar(  time, lower, yerr=( nn*[0], delta), ls='', ecolor="#00C023"  )
ax.scatter( time[ inside ], data[ inside ], c='k' )
ax.scatter( time[ outside ], data[ outside ], c='r' )
plt.show()
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement