简体   繁体   中英

how to plot data , prediction bar with supblots?

I want to plot my data with using suplots. For each graph I try to plot the linear regression line, the confidence bars and the prediction bars. My code works correctly without subplots. But, the latter is mandatory. I try to plot data, linear regression, confidence interval, prediction interval in the same subplots. This is my code with :

import matplotlib.pyplot as plt
plt.style.use('ggplot')
from pylab import *
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
from scipy import stats

try:
    import uncertainties.unumpy as unp
    import uncertainties as unc
except:
    import pip
    pip.main(['install','uncertainties'])
    import uncertainties.unumpy as unp
    import uncertainties as unc


def f(x, a, b):
    return a * x + b


def Convert_ASN_Decimal(asn_hex):
    asn_dec = asn_hex[5] + asn_hex[2:4] + asn_hex[0:2]
    reversed = int(asn_dec, 16)
    return (reversed)

def predband(x, xd, yd, p, func, conf=0.95):
    # x = requested points
    # xd = x data
    # yd = y data
    # p = parameters
    # func = function name
    alpha = 1.0 - conf    # significance
    N = xd.size          # data sample size
    var_n = len(p)  # number of parameters
    # Quantile of Student's t distribution for p=(1-alpha/2)
    q = stats.t.ppf(1.0 - alpha / 2.0, N - var_n)
    # Stdev of an individual measurement
    se = np.sqrt(1. / (N - var_n) * np.sum((yd - func(xd, *p)) ** 2))
    # Auxiliary definitions
    sx = (x - xd.mean()) ** 2
    sxd = np.sum((xd - xd.mean()) ** 2)
    # Predicted values (best-fit model)
    yp = func(x, *p)
    # Prediction band
    dy = q * se * np.sqrt(1.0+ (1.0/N) + (sx/sxd))
    # Upper & lower prediction bands.
    lpb, upb = yp - dy, yp + dy
    return lpb, upb


plots = {'02141592cc00000004': {
    'dest': ['1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4', '5', '6', '7',
             '1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4', '5', '6', '7'],
    'data': [39794, 39996, 40400, 42218, 42420, 43026, 43632, 45450, 45652, 46258, 46460, 46662, 47066, 49086, 50096,
             50298, 50500, 50904, 51106, 52116, 52318, 53328, 53732, 55146, 55954, 56560, 56762, 56964, 57166, 57772,
             58984, 59388, 60196, 63024, 64438],
    'timestamp': [1549033439, 1549033441, 1549033443, 1549033453, 1549033454, 1549033458, 1549033462, 1549033477,
                  1549033479, 1549033483, 1549033484, 1549033485, 1549033488, 1549033502, 1549033510, 1549033512,
                  1549033513, 1549033516, 1549033517, 1549033524, 1549033526, 1549033533, 1549033535, 1549033546,
                  1549033552, 1549033557, 1549033558, 1549033559, 1549033561, 1549033564, 1549033571, 1549033573,
                  1549033578, 1549033599, 1549033610]}, '02141592cc00000003': {
    'dest': ['1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4', '5', '6', '7',
             '1', '2', '3', '4', '5', '6', '7', '1', '2', '3', '4', '5', '6', '7'],
    'data': [39794, 39996, 40400, 42218, 42420, 43026, 43632, 45450, 45652, 46258, 46460, 46662, 47066, 49086, 50096,
             50298, 50500, 50904, 51106, 52116, 52318, 53328, 53732, 55146, 55954, 56560, 56762, 56964, 57166, 57772,
             58984, 59388, 60196, 63024, 64438],
    'timestamp': [1549033439, 1549033441, 1549033443, 1549033453, 1549033454, 1549033458, 1549033462, 1549033477,
                  1549033479, 1549033483, 1549033484, 1549033485, 1549033488, 1549033502, 1549033510, 1549033512,
                  1549033513, 1549033516, 1549033517, 1549033524, 1549033526, 1549033533, 1549033535, 1549033546,
                  1549033552, 1549033557, 1549033558, 1549033559, 1549033561, 1549033564, 1549033571, 1549033573,
                  1549033578, 1549033599, 1549033610]}}

f, ax = plt.subplots(len(plots), 1, figsize=(50, 30))
plt.suptitle('Data')
plt.subplots_adjust(hspace=2)
for i, item in enumerate(plots):
    print(i)
    print(item)
    y = [x for _, x in sorted(zip(plots[item]['timestamp'], plots[item]['data']))]
    x = sorted(plots[item]['timestamp'])
    ax[i].scatter(x, y, s=20)
    ax[i].set_ylabel('data')
    ax[i].set_xlabel('timestamp')
    ax[i].set_title(str(item))


    x = np.array(x)
    y = np.array(y)
    n=len(y)
    popt, pcov = curve_fit(f, x, y)
    # retrieve parameter values
    a = popt[0]
    b = popt[1]
    print('Optimal Values')
    print('a: ' + str(a))
    print('b: ' + str(b))

    # compute r^2
    r2 = 1.0 - (sum((y - f(x, a, b)) ** 2) / ((n - 1.0) * np.var(y, ddof=1)))
    print('R^2: ' + str(r2))

    # calculate parameter confidence interval
    a, b = unc.correlated_values(popt, pcov)
    print('Uncertainty')
    print('a: ' + str(a))
    print('b: ' + str(b))

    # plot data
    plt.scatter(x, y, s=3, label='Data')

    # calculate regression confidence interval
    px = np.linspace(14, 24, n)
    print(px)
    py = a * px + b
    print(py)
    nom = unp.nominal_values(py)
    print(nom)
    std = unp.std_devs(py)
    print(std)

    lpb, upb = predband(px, x, y, popt, f, conf=0.95)

    # plot the regression
    plt.plot(px, nom, c='black', label='y=a x + b')

    # uncertainty lines (95% confidence)
    plt.plot(px, nom - 1.96 * std, c='orange', label='95% Confidence Region')
    plt.plot(px, nom + 1.96 * std, c='orange')
    # prediction band (95% confidence)
    plt.plot(px, lpb, 'k--', label='95% Prediction Band')
    plt.plot(px, upb, 'k--')
    plt.ylabel('y')
    plt.xlabel('x')
    plt.legend(loc='best')
plt.show()

But it gives me this error:

Traceback (most recent call last):
  File "Test.py", line 92, in <module>
    popt, pcov = curve_fit(f, x, y)
  File "path/lib/python3.5/site-packages/scipy/optimize/minpack.py", line 678, in curve_fit
    args, varargs, varkw, defaults = _getargspec(f)
  File "path/lib/python3.5/site-packages/scipy/_lib/_util.py", line 291, in getargspec_no_self
    sig = inspect.signature(func)
  File "/usr/lib/python3.5/inspect.py", line 2987, in signature
    return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
  File "/usr/lib/python3.5/inspect.py", line 2737, in from_callable
    follow_wrapper_chains=follow_wrapped)
  File "/usr/lib/python3.5/inspect.py", line 2156, in _signature_from_callable
    raise TypeError('{!r} is not a callable object'.format(obj))
TypeError: <Figure size 5000x3000 with 2 Axes> is not a callable object

The error message is saying that the argument f is not what curve_fit expect. After checking your code, I found that you first create a function named f , and then you create another f when calling f, ax = plt.subplots(len(plots), 1, figsize=(50, 30)) .

You should just rename the second f to some other name and the problem be solved.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM