Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I shade an area under a curve between two lines in matplotlib / pandas?

I'm trying to recreate this chart, more or less, using matplotlib:

enter image description here

Except in mine the center is 100 and the standard deviation is 16 (like IQ). This is what I have so far:

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats as stats
x = np.linspace(50,150,100)
iq = stats.norm.pdf(x, 100, 16)
plt.plot(x,iq)

That generates a normal curve like this:

enter image description here

So far so good. But I'm at a loss for how to shade areas under the curve.

like image 732
Jonathan Avatar asked May 26 '16 19:05

Jonathan


People also ask

How do you highlight area under a curve in Python?

To fill the area under the curve, put x and y with ste="pre", using fill_between() method. Plot (x, y1) and (x, y2) lines using plot() method with drawstyle="steps" method. To display the figure, use show() method.

How do I shade an area in MatPlotLib?

MatPlotLib with Python To shade an area parallel to X-axis, initialize two variables, y1 and y2. To add horizontal span across the axes, use axhspan() method with y1, y2, green as shade color,and alpha for transprency of the shade. To display the figure, use show() method.

How do you fill an area between two lines in python?

You can easily fill in the area between values in a Matplotlib plot by using following functions: fill_between(): Fill the area between two horizontal curves. fill_betweenx(): Fill the area between two vertical curves.


1 Answers

You can use plt.fill_between:

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

plt.style.use('ggplot')

mean = 100
std = 16

x = np.linspace(mean - 5 * std, mean + 5 * std, 1000)

iq = stats.norm(mean, std)

plt.plot(x, iq.pdf(x), 'r-', lw=3)

colors = ['c', 'r', 'b', 'g', ]
colors = colors + list(reversed(colors))

for i, color in zip(range(-4, 4), colors):
    low = mean + i * std
    high = mean + (i + 1) * std
    px = x[np.logical_and(x >= low, x <= high)]
    plt.fill_between(
        px,
        iq.pdf(px),
        color=color,
        alpha=0.5,
        linewidth=0,
    )

plt.tight_layout()
plt.savefig('test.png', dpi=300)

result

like image 132
MaxNoe Avatar answered Sep 18 '22 18:09

MaxNoe