Printing a variable with matplotlib ax.text printing a list of values instead of a number?
I am currently trying to create a program that will plot a function using matplotlib, draw it, shade the area under the curve between two variables, and use Simpson's 3 / 8th rule to calculate the shaded area. However, when I try to print the variable that I assigned the final value of the integral, it prints a list.
To get started, here is the base of my code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Polygon
This definition defines the function I will be working with here, a simple polynomial.
def func(x):
return (x - 3) * (x - 5) * (x - 7) + 85
Here is a function that calculates the area under a curve
def simpson(function, a, b, n):
"""Approximates the definite integral of f from a to b by the
composite Simpson rule, using n subintervals (with n even)"""
if n % 2:
raise ValueError("n must be even (received n=%d)" % n)
h = (b - a) / n #The first section of Simpson 3/8ths rule
s = function(a) + function(b) #The addition of functions over an interval
for i in range(1, n, 2):
s += 4 * function(a + i * h)
for i in range(2, n-1, 2):
s += 2 * function(a + i * h)
return s * h / 3
The simpson rule definition is now complete, and for the sake of simplicity, I am defining a few variables.
a, b = 2, 9 # integral limits
x = np.linspace(0, 10) #Generates 100 points evenly spaced between 0 and 10
y = func(x) #Just defines y to be f(x) so its ez later on
fig, ax = plt.subplots()
plt.plot(x, y, 'r', linewidth=2)
plt.ylim(ymin=0)
final_integral = simpson(lambda x: y, a, b, 100000)
Something should break at this point, but I'll add the rest of the code if you can still identify the problem.
# Make the shaded region
ix = np.linspace(a, b)
iy = func(ix)
verts = [(a, 0)] + list(zip(ix, iy)) + [(b, 0)]
poly = Polygon(verts, facecolor='0.9', edgecolor='0.5')
ax.add_patch(poly)
plt.text(0.5 * (a + b), 30, r"$\int_a^b f(x)\mathrm{d}x$",
horizontalalignment='center', fontsize=20)
ax.text(0.25, 135, r"Using Simpson 3/8ths rule, the area under the curve is: ", fontsize=20)
The integral value should be printed here:
ax.text(0.25, 114, final_integral , fontsize=20)
Here's the rest of the code needed to plot the graph:
plt.figtext(0.9, 0.05, '$x$')
plt.figtext(0.1, 0.9, '$y$')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.xaxis.set_ticks_position('bottom')
ax.set_xticks((a, b))
ax.set_xticklabels(('$a$', '$b$'))
ax.set_yticks([])
plt.show()
Any help is appreciated here. I am completely stuck. Also, sorry if this is a bit, this is my first question on the forum.
source to share
Have you tried using simpson () func () function directly rather than using lambda setting?
I think this might work:
final_integral = simpson(func, a, b, 100000)
You can also try:
final_integral = simpson(lambda x: func(x), a, b, 100000)
What happens is that y is an array with the values func (x) , and when you use an expression lambda x: y
, you are actually creating a constant function of the form f (x) = y = const . Yours final_integral
is a list of integrals, where each integrand is a constant function with a specific value from the array y .
Note that you can format this number when you print it out on the graph in case it has many trailing decimal points. How you do this depends on whether you are using Python 2 or 3 .
source to share
You assigned x as linspace, which is an array so y is also an array of the values of the x function. You can replace this line of code:
#old:
final_integral = simpson(lambda x:y, a, b, 100000)
#new:
final_integral = simpson(lambda t:func(t), a, b, 100000)
Changing the variable from x to t will give you the value for the area under that curve. Hope this helps.
source to share