bluevoxel
bluevoxel

Reputation: 5358

How to plot the area of given integration?

I have the following script:

import numpy as np

def f(x):
    return x**2 + 3

def integration(a, b, n):
    dx = (b - a) / n
    integration = 0
    for i in np.arange(1, n + 1):
        integration += f(a + i * dx)
    integration *= dx
    return integration 

print(integration (0, 5, 10000))

Now, I want to plot the curve of the f(x) in the range described by a and b with integration area beneath it, so I can get something like this:

enter image description here

I know how to do the first part, ie plot the f(x) curve in a specific range:

import matplotlib.pylab as pl

x = np.linspace(0, 5, 10000)

def f(x):
    return x**2 + 3

pl.plot(x, f(x))
pl.xlim([-1, 6])
pl.show()

...but I lack the rest. I'll be grateful for help.

Upvotes: 2

Views: 2708

Answers (2)

bluevoxel
bluevoxel

Reputation: 5358

Thanks to @Evert comment here is a working solution:

'''
According to the rectangle rule.
'''
import numpy as np
import matplotlib.pylab as pl
from matplotlib.patches import Polygon

# Function definition.
def f(x):
    return x ** 2 + 3

# Integration calculation.
def integration(a, b, n):
    dx = (b - a) / n
    integration = 0
    for i in np.arange(1, n + 1):
        integration += f(a + i * dx)
    integration *= dx
    return integration

# Define integral limits.
a, b = 0, 5

# Define x and y arrays.
x = np.linspace(0, 10, 10000)
y = f(x)

# Plot x and y.
fig, ax = pl.subplots()
pl.plot(x, y, 'b', linewidth = 2)
pl.xlim(xmin = -1, xmax = 11)
pl.ylim(ymin = 0)

# Shade area of the integration beneath the f(x) curve.
ix = np.linspace(a, b, 10000)
iy = f(ix)
verts = [(a, 0)] + list(zip(ix, iy)) + [(b, 0)]
poly = Polygon(verts, facecolor = '0.9', edgecolor = '0.5')
ax.add_patch(poly)

# Print equation text.
pl.text(0.5 * (a + b), 60, r"$\int_{a}^{b}f(x)dx=%.2f$" %integration(a, b, 10000),
horizontalalignment = 'center', fontsize = 20)

# Add x and y axes labels.
pl.figtext(0.9, 0.05, '$x$')
pl.figtext(0.1, 0.9, '$y$')

# Remove right and top plot delimeter lines.
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.xaxis.set_ticks_position('bottom')

# Add a and b ticks on x axis.
ax.set_xticks((a, b))
ax.set_xticklabels(('$a=%d$' %a, '$b=%d$' %b))
ax.set_yticks([])

# Show the plot.
pl.show()

enter image description here

Upvotes: 4

Johan
Johan

Reputation: 343

First, consider renaming the variable integration to intresult or something. There may come confusion between the function name and variable name.

As for the question at hand, you can use the pl.plot function multiple times on the same set of axes to create extra lines. As such you can plot two vertical lines (the ones represented by thick black lines in your illustration) with something like the following code:

pl.plot([a,a], [0,f(a)], "k-")
pl.plot([b,b], [0,f(b)], "k-")

In this code, "k-" represents that the plot should be a black (k) line (-). This is a function in matplotlib.pyplot, so I'm not sure if it works with matplotlib.pylab.

Similarly, red points can be created with calls like pl.plot([a], [f(a)], "r."). Again, this applies to pyplot, but may also work for pylab.

As for the area, I don't know of any dedicated area-filling functions. However, you could try line-shading the area with multiple blue vertical lines, by repeatedly calling pl.plot([x,x], [0,f(x)], "b-") for different values of x. It's a messy solution, but one you can try.

Experiment with different functionalities, and consider trying pyplot instead of pylab if any of my solutions do not work.

Upvotes: 0

Related Questions