1

I have plotted a graph with dataset df, where Timestamp is the index:

df:

      Timestamp     Temperature     
2020-02-06 08:23:04 18.5    
2020-02-06 08:23:05 18.5    
2020-02-06 08:23:06 18.5    
2020-02-06 08:23:07 18.5    
2020-02-06 08:23:08 18.5    
... ... ...
2020-02-06 20:14:36 21.0    

and code

df.plot( y='Temperature', figsize=(16, 10),) 
plt.axhline(y=40, color='r', linestyle='-')
plt.axhline(y=25, color='b', linestyle='-')
plt.show()

The graph looks like this:

enter image description here

I would like to fill in colour for area where temperature is between 25°C and 40°C(inside the triangle). Can I do this by tweaking my code? If not, what's a good way of doing this? Thanks!

Note: The data is not continuous, but has been forward filled to have constant interval of 1 second. Also, temperature at the peak is above 40°C and the corresponding vertical section in Timestamp should not be coloured.

nilsinelabore
  • 4,143
  • 17
  • 65
  • 122

1 Answers1

3

I can suggest this approach using fill_between using the where argument:

Timestamp = pd.date_range('2020-02-06 08:23:04', periods=1000, freq='s')
df = pd.DataFrame({'Timestamp': Timestamp,
                   'Temperature': 30+15*np.cos(np.linspace(0,10,Timestamp.size))})

df['top_lim'] = 40.
df['bottom_lim'] = 25.

plt.plot_date(df['Timestamp'], df['Temperature'], '-')
plt.plot_date(df['Timestamp'], df['top_lim'], '-', color='r')
plt.plot_date(df['Timestamp'], df['bottom_lim'], '-', color='blue')

plt.fill_between(df['Timestamp'], df['bottom_lim'], df['Temperature'],
                where=(df['Temperature'] >= df['bottom_lim'])&(df['Temperature'] <= df['top_lim']),
                facecolor='orange', alpha=0.3)

########### EDIT ################

# plt.fill_between(df['Timestamp'], df['bottom_lim'], df['top_lim'],
#                 where=(df['Temperature'] >= df['top_lim']),
#                 facecolor='orange', alpha=0.3)


mask = (df['Temperature'] <= df['top_lim'])&(df['Temperature'] >= df['bottom_lim'])
plt.scatter(df['Timestamp'][mask], df['Temperature'][mask], marker='.', color='black')
cumulated_time = df['Timestamp'][mask].diff().sum()
plt.title(f'Cumulated time in range = {cumulated_time}')
plt.show()

enter image description here

Andrea
  • 2,932
  • 11
  • 23
  • Hi Andrea, thanks for the solution. Would it be possible to exclude the portion where the curve exceeds 40? Because I want to calculate the accumulated time where temperature is between 25 and 40 – nilsinelabore Feb 06 '20 at 10:47
  • I'm not sure I got what you are asking. Does the edit answer your question? – Andrea Feb 06 '20 at 10:55
  • Yes this is exactly what I want! Just one question, is there a way to replace `.diff`? As column `Timestamp ` is `index` format, it returned `AttributeError: 'DatetimeIndex' object has no attribute 'diff'` – nilsinelabore Feb 06 '20 at 12:13
  • [Here's](https://stackoverflow.com/questions/49277932/difference-pandas-datetimeindex-without-a-frequency) the answer :) – Andrea Feb 06 '20 at 13:02