RnRoger
RnRoger

Reputation: 690

matplotlib graph fill 2 colors above and below axis

I have a line graph which is partly above and below the x-axis of 0. How can I color all the area above the line green, and all below red? Here's the code:

hydropathy_dict = {"I":-0.528, 
        "L":-0.342,
        "F":-0.370,
        "V":-0.308,
        "M":-0.324,
        "P":-0.322,
        "W": -0.270,
        "H": 2.029,
        "T": 0.853,
        "E": 3.173,
        "Q": 2.176,
        "C": 0.081,
        "Y": 1.677,
        "A":-0.495,
        "S": 0.936,
        "N": 2.354,
        "D": 9.573,
        "R": 4.383,
        "G": 0.386,
        "K": 2.101
        }
    seq = 'CHCRRSCYSTEYSYGTCTVMGINHRFCC'
    hydropathy_list = []
    plot_x_axis = []
    for aa in seq:
        hydropathy_list.append(hydropathy_dict[aa])
    print(acc,hydropathy_list)
    for i in range(len(hydropathy_list)):
        plot_x_axis.append(i)

    plt.plot(plot_x_axis,hydropathy_list)
    plt.plot([0,len(hydropathy_list)],[0,0])
    plt.show()

Upvotes: 1

Views: 2911

Answers (3)

swatchai
swatchai

Reputation: 18772

Try this:

import matplotlib.pyplot as plt
import numpy as np
from scipy import interpolate

hydropathy_dict = {"I":-0.528, 
        "L":-0.342,
        "F":-0.370,
        "V":-0.308,
        "M":-0.324,
        "P":-0.322,
        "W": -0.270,
        "H": 2.029,
        "T": 0.853,
        "E": 3.173,
        "Q": 2.176,
        "C": 0.081,
        "Y": 1.677,
        "A":-0.495,
        "S": 0.936,
        "N": 2.354,
        "D": 9.573,
        "R": 4.383,
        "G": 0.386,
        "K": 2.101
        }

seq = 'CHCRRSCYSTEYSYGTCTVMGINHRFCC'
hydropathy_list = []
plot_x_axis = []
for aa in seq:
    hydropathy_list.append(hydropathy_dict[aa])

#print(seq, hydropathy_list)
for i in range(len(hydropathy_list)):
    plot_x_axis.append(i)

# convert to np array
hydropathy_list = np.array(hydropathy_list)
plot_x_axis = np.array(plot_x_axis)

# densify data for filled color plot
f = interpolate.interp1d(plot_x_axis, hydropathy_list)
xnew = np.arange(plot_x_axis[0], plot_x_axis[-1], 0.1)
ynew = f(xnew)

plt.plot(plot_x_axis, hydropathy_list)       # blue line
plt.plot([0, len(hydropathy_list)], [0,0])   # green line

# use xnew, ynew to plot filled-color graphs
plt.fill_between(xnew, 0, ynew, where=(ynew-1) < -1 , color='red')
plt.fill_between(xnew, 0, ynew, where=(ynew-1) > -1 , color='green')

plt.show()

with interpolated points

Edit

(In response of the questions in the comment)

Statement where=(ynew-1)<-1 inside fill_between() requires ynew as a numpy array (simple list won't work).

Scipy.interpolate() is used to get more points along the curve, so that, the color fills the target areas completely.

With the original points, the result looks like this:

with original points

Upvotes: 2

Grr
Grr

Reputation: 16079

Take a look at the matplotlib fill-between demo. That will surely answer your question.

But that being said your code doesn't show any figure definition which makes this more difficult. Usually you do the following:

fig, ax = plt.figure()
ax.plot(plot_x_axis, line_1)
ax.plot(plot_x_axis, line_2)
ax.fill_between(plot_x_axis, line_1, line_2, color='r')
ax.fill_between(plot_x_axis, line_2, line_1, color='g')

Upvotes: 1

litepresence
litepresence

Reputation: 3277

use this format:

import matplotlib.pyplot as plt

x = range(10)
plt.fill_between(x,0,100,color='red')
plt.fill_between(x,0,-100,color='blue')

plt.show()

Upvotes: 0

Related Questions