简体   繁体   中英

Changing colours crossing zero pyplot Python

I want to code a Pyplot graph where it changes colors below the negative mark. I have conditions stated at the Color Conditions section. how would i be able to get this to work?

import pandas as pd 
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
from matplotlib.dates import DateFormatter

df = pd.DataFrame({'col1': [4, 5, 2, 2, 3, 5, 1, 1, 6],  
     'label':['Old','Old','Old','Old','Old','Old','Old','Old','Old'],
     'date': ['2022-01-24 10:07:02', '2022-01-27 01:55:03', '2022-01-30 19:09:03', '2022-02-02 14:34:06',
              '2022-02-08 12:37:03', '2022-02-10 03:07:02', '2022-02-10 14:02:03', '2022-02-11 00:32:25',
              '2022-02-12 21:42:03']})

CumSum_val = np.cumsum(df['col1'])
datetime = pd.to_datetime(df['date'])

#Color conditions
green_cond = np.where(CumSum_val > 0)
red_cond =  np.where(CumSum_val <= 0)

# Define the date format
date_form = DateFormatter("%m-%d")
plt.xaxis.set_major_formatter(date_form)

plt.plot(datetime[green_cond],CumSum_val[green_cond], color = 'g')
plt.plot(datetime[red_cond],CumSum_val[red_cond], color = 'r')

plt.show()

You can try plot three lines with different color, the latter has prior priority to show color.

green_cond = CumSum_val > 0
red_cond =  CumSum_val <= 0

fig = plt.figure()
ax = fig.add_subplot(111)

ax.plot(datetime, CumSum_val, color='b')
ax.plot(datetime[green_cond], CumSum_val[green_cond], color='g')
ax.plot(datetime[red_cond], CumSum_val[red_cond], color='r')

# Define the date format
date_form = DateFormatter("%m-%d")
ax.xaxis.set_major_formatter(date_form)

plt.show()

在此处输入图像描述

The data you provided doesn't cross zero, so I took the liberty to modify this value to a given threshold , 15 in the below example. You can change it to whatever value you like.

The idea is to insert a new point every time the line crosses the threshold. Linear interpolation was used to achieve it. Then, to properly plot the two lines you need to select the points with:

green_cond = CumSum_val >= threshold
red_cond =  CumSum_val <= threshold

Note that I used >= and <= because I want the lines to share the common threshold point.

import pandas as pd 
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.dates as mdates
from matplotlib.dates import DateFormatter, date2num, num2date

df = pd.DataFrame({'col1': [4, 5, 2, 2, 3, 5, 1, 1, 6],  
     'label':['Old','Old','Old','Old','Old','Old','Old','Old','Old'],
     'date': ['2022-01-24 10:07:02', '2022-01-27 01:55:03', '2022-01-30 19:09:03', '2022-02-02 14:34:06',
              '2022-02-08 12:37:03', '2022-02-10 03:07:02', '2022-02-10 14:02:03', '2022-02-11 00:32:25',
              '2022-02-12 21:42:03']})

def modify_coords(x, y, y_lim):
    """If a line segment defined by `(x1, y1) -> (x2, y2)` intercepts
    a limiting y-value, divide this segment by inserting a new point
    such that y_newpoint = y_lim.
    """
    xv, yv = [x[0]], [y[0]]
    for i in range(len(x) - 1):
        xc, xn = x[i:i+2]
        yc, yn = y[i:i+2]
        if ((yc < y_lim) and (yn > y_lim)) or ((yc > y_lim) and (yn < y_lim)):
            xv.append(((y_lim - yc) / ((yn - yc) / (xn - xc))) + xc)
            yv.append(y_lim)
        xv.append(xn)
        yv.append(yn)
    return np.array(xv), np.array(yv)

CumSum_val = np.cumsum(df['col1'])
datetime = pd.to_datetime(df['date'])
datenum = date2num(datetime)

threshold = 15
datenum, CumSum_val = modify_coords(datenum, CumSum_val, threshold)
datetime = np.array(num2date(datenum))

#Color conditions
green_cond = CumSum_val >= threshold
red_cond =  CumSum_val <= threshold

fig, ax = plt.subplots()

# Define the date format
date_form = DateFormatter("%m-%d")
ax.xaxis.set_major_formatter(date_form)

ax.plot(datetime[green_cond], CumSum_val[green_cond], color = 'g')
ax.plot(datetime[red_cond], CumSum_val[red_cond], color = 'r')

plt.show()

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM