Making parts of a line graph a different colour depending on their y value in Matplotlib

Viewed 47

I'm making a program which takes a random list of data and will plot it. I want the colour of the graph to change if it goes above a certain value.

https://matplotlib.org/gallery/lines_bars_and_markers/multicolored_line.html Matplotlib has an entry on doing just this but it seems to require using a function as input for the graph not using lists.

Does anyone know how to either convert this to work for lists or another way of doing so?

Here's my code so far (without my horrific failed attempts to colour code them)

from matplotlib import pyplot as plt
import random
import sys
import numpy as np

#setting the max and min values where I want the colour to change
A_min = 2
B_max = 28

#makes lists for later
A_min_lin = []
B_max_lin = []

#simulating a corruption of the data where it returns all zeros
sim_crpt = random.randint(0,10)
print(sim_crpt)
randomy = []
if sim_crpt == 0:
    randomy = []
    #making the empty lists for corrupted data
    for i in range(0,20):
        randomy.append(0)
    print(randomy)
else:
    #making a random set of values for the y axis
    for i in range(0,20):
        n = random.randint(0,30)
        randomy.append(n)
    print(randomy)


#making an x axis for time
time = t = np.arange(0, 20, 1)

#Making a list to plot a straight line showing where the maximum and minimum values
for i in range(0, len(time)):
    A_min_lin.append(A_min)
    B_max_lin.append(B_max)


#Testing to see if more than 5 y values are zero to return if it's corrupted
tracker = 0
for i in (randomy):
    if i == 0:
        tracker += 1
    if tracker > 5:
        sys.exit("Error, no data")

#ploting and showing the different graphs
plt.plot(time,randomy)
plt.plot(time,A_min_lin)
plt.plot(time,B_max_lin)
plt.legend(['Data', 'Minimum for linear', "Maximum for linear"])
plt.show
1 Answers

You can use np.interp to generate the fine-grain data to plot:

# fine grain time
new_time = np.linspace(time.min(), time.max(), 1000)

# interpolate the y values
new_randomy = np.interp(new_time, time, randomy)

# this is copied from the link with few modification
points = np.array([new_time, new_randomy]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)

fig, axs = plt.subplots()
norm = plt.Normalize(new_randomy.min(), new_randomy.max())
lc = LineCollection(segments, cmap='viridis', norm=norm)
# Set the values used for colormapping
lc.set_array(new_randomy[1:])
lc.set_linewidth(2)
line = axs.add_collection(lc)
fig.colorbar(line, ax=axs)

# set the limits
axs.set_xlim(new_time.min(), new_time.max())
axs.set_ylim(new_randomy.min(), new_randomy.max())
plt.show()

Output:

enter image description here

Related