24 czerwca 2016

[python] matplotlib - rysowanie wykresów

Kolejna biblioteka, którą zacząłem się bawić, służąca do rysowania wykresów: matplotlib. Bardzo przyjema dokumentacja, z dużą liczbą przykładów. Dla testu wykreśliłem pochodną i całkę oznaczoną dla funkcji:
$$ f(x) = -2x^{3} - 4x^{2} + 8x + 1 \\
f^\prime(x) = -6x^{2} - 8x + 8 \\
F(x) = \int f(x) dx = -\frac{1}{2}x^{4} - \frac{4}{3}x^{3} + 4x^{2} + x + C \\
F(-3) - F(1) = \int_{-3}^{1} f(x) dx = \left(-\frac{1}{2}x^{4} - \frac{4}{3}x^{3} + 4x^{2} + x + C\right)\Biggr|_{-3}^{1} $$
Kod programu:
#!/usr/bin/env python
# -*- coding: utf-8 -*-


import numpy as np
import matplotlib.patches as mpatches
import matplotlib.pyplot as plt


def main():
    red_patch = mpatches.Patch(color='red', label=r'$f(x)$ - moja funkcja')
    blue_patch = mpatches.Patch(color='blue', label=r'$f^\prime(x)$ - obliczone numerycznie')
    cyan_patch = mpatches.Patch(color='cyan', label=r'$f^\prime(x)$ - obliczone recznie')
    green_patch = mpatches.Patch(color='green', label=r"$\int_{-3}^{1}f(x)$ - obliczone numerycznie")

    plt.legend(handles=[red_patch, blue_patch, cyan_patch, green_patch], loc='lower right')

    x = np.linspace(-4, 2, 10)
    x_dense = np.linspace(-4, 2)

    y_f = func(x)
    plt.plot(x, y_f, 'red', linewidth=2)

    y_deriv = derivative(func, x)
    plt.plot(x, y_deriv, 'blue', linewidth=2)

    y_own_deriv = own_deriv_func(x_dense)
    plt.plot(x_dense, y_own_deriv, 'cyan', linewidth=1)

    summo1 = definite_integral(func, a=-3, b=1)
    summo2 = own_integral_func(a=-3, b=1)
    print 'Całka oznaczona, numerycznie: %f' % summo1
    print 'Całka oznaczona, ręcznie: %f' % summo2

    current_figure = plt.gcf()
    current_figure.savefig('rachunek_rozniczkowy.png')

    plt.show()


def func(x):
    return -2 * (x ** 3) - 4 * (x ** 2) + (8 * x) + 1


def own_deriv_func(x):
    return -6 * (x ** 2) - 8 * x + 8


def own_integral_func(a, b):
    F = lambda x: -(1/2.0) * (x ** 4) - (4/3.0) * (x ** 3) + 4 * (x ** 2) + x
    return F(b) - F(a)


def derivative(fun, x):
    h = 0.2 # dx
    return (fun(x + h) - fun(x)) / h


def definite_integral(fun, a, b):
    axes = plt.gca()
    dx = (b - a) / 20.0

    summo = 0
    x = a
    while x < b:
        axes.add_patch(mpatches.Rectangle(xy=(x, 0), width=dx, height=fun(x), facecolor='green'))
        summo += dx * fun(x)
        x += dx

    return summo


if __name__ == '__main__':
    main()
Wynik:
Całka oznaczona, numerycznie: -26.080000
Całka oznaczona, ręcznie: -25.333333

Brak komentarzy:

Prześlij komentarz