How can I plot 1-d list onto existing plot without knowing x locations?

Viewed 55

I am plotting a graph with datetime and power which can be seen in the big blue line on the attached image.

After plotting the image, I am trying to insert the 1-d list (only_unusual) in the same plot.

Actually df['power'] includes the values of the 1-d list (only_unusual).

But without including y axis alongside with only_unusual I can't plot the graph.

How can I plot the only_unusual list in the same plot so that it will be visible on the main blue line with a different color?

My code:

fig, ax = plt.subplots(figsize=(16,12))
ax.plot(pd.to_datetime(df['datetime']), df['power'], color='b',label='Normal')
ax.scatter(only_unusual ,  color='red', label='Unusual',marker='o')
ax.xaxis_date()
plt.xlabel('Date Time')
plt.ylabel('power')
plt.legend()
fig.autofmt_xdate()
plt.show()

My main plot

My data:

only_unusual : [13.266, 4.213291, 2.756, 3.6722, 12.356, 12.193, 10.318, 12.203, 8.7549, 9.536, 9.10677, 1.417]




df :

        datetime              invno  power
0       2021-12-01 00:00:00    1     0.000
5       2021-12-01 01:00:00    1     0.000
10      2021-12-01 02:00:00    1     0.000
15      2021-12-01 03:00:00    1     0.000
20      2021-12-01 04:00:00    1     0.000
....     ...... ...... ....    ..     .....

1129    2021-12-10 09:00:00    5    2.914
1134    2021-12-10 10:00:00    5    10.318

...     ... ... ...
1149    2021-12-10 13:00:00    5     2.756
1154    2021-12-10 14:00:00    5     1.297
1159    2021-12-10 15:00:00    5     1.503
1164    2021-12-10 16:00:00   5      1.417
1169    2021-12-10 17:00:00    5     0.084
1170 rows × 3 columns
1 Answers

If the list contains y values (power)

Normally we could find matching y values with isin, but since these are floats, we should use np.isclose to check with a tolerance.

  1. Use np.isclose with array broadcasting to find matches with some tolerance:

    matches = df[np.isclose(df['power'].values[:, None], only_unusual).any(axis=1)]
    
    #                  datetime  invno   power
    # 1134  2021-12-10 10:00:00      5  10.318
    # 1149  2021-12-10 13:00:00      5   2.756
    # 1164  2021-12-10 16:00:00      5   1.417
    
  2. Then scatter plot these matches:

    ax.scatter(pd.to_datetime(matches['datetime']), matches['power'], color='r', label='Unusual', marker='o')
    #                         ^^^^^^^               ^^^^^^^
    

Full code (pandas 1.3.3, numpy 1.20.3, matplotlib 1.3.5):

df = pd.DataFrame({'datetime': {0: '2021-12-01 00:00:00', 5: '2021-12-01 01:00:00', 10: '2021-12-01 02:00:00', 15: '2021-12-01 03:00:00', 20: '2021-12-01 04:00:00', 1129: '2021-12-10 09:00:00', 1134: '2021-12-10 10:00:00', 1149: '2021-12-10 13:00:00', 1154: '2021-12-10 14:00:00', 1159: '2021-12-10 15:00:00', 1164: '2021-12-10 16:00:00', 1169: '2021-12-10 17:00:00'}, 'invno': {0: 1, 5: 1, 10: 1, 15: 1, 20: 1, 1129: 5, 1134: 5, 1149: 5, 1154: 5, 1159: 5, 1164: 5, 1169: 5}, 'power': {0: 0.0, 5: 0.0, 10: 0.0, 15: 0.0, 20: 0.0, 1129: 2.914, 1134: 10.318, 1149: 2.756, 1154: 1.297, 1159: 1.503, 1164: 1.417, 1169: 0.084}})
only_unusual = [13.266, 4.213291, 2.756, 3.6722, 12.356, 12.193, 10.318, 12.203, 8.7549, 9.536, 9.10677, 1.417]

matches = df[np.isclose(df['power'].values[:, None], only_unusual).any(axis=1)]

fig, ax = plt.subplots(figsize=(8, 6))
ax.plot(pd.to_datetime(df['datetime']), df['power'], color='b', label='Normal')
ax.scatter(pd.to_datetime(matches['datetime']), matches['power'], color='r', label='Unusual', marker='o')
ax.xaxis_date()
plt.xlabel('Date Time')
plt.ylabel('Power')
plt.legend()
fig.autofmt_xdate()


If the list contains x values (datetime)

  1. We can just use isin to find matching datetime rows:

    matches = df[df['datetime'].isin(only_unusual)]
    
  2. Then use these matches (instead of df) for the scatter plot:

    ax.scatter(pd.to_datetime(matches['datetime']), matches['power'], color='r', label='Unusual', marker='o')
    #                         ^^^^^^^               ^^^^^^^
    
Related