def show_uncertainty(results, show_errors=False):
    data_size = results['data_size']
    IQRs_RMSE = results['model_uncertainty']
    IQRs_RMSE = np.array([np.mean((np.exp(I['uncertainty_high']) - np.exp(I['uncertainty_low']))) for I in results['iterations_results']])
    IQRs_std = np.array([np.std((np.exp(I['uncertainty_high']) - np.exp(I['uncertainty_low']))) for I in results['iterations_results']])
    (fig, ax) = plt.subplots(figsize=(8, 2))
    if show_errors:
        ax.errorbar(np.arange(len(IQRs_RMSE)), IQRs_RMSE, yerr=IQRs_std, fmt='o', label='Uncertainty')
    else:
        ax.plot(IQRs_RMSE, marker='o', label='Uncertainty')
    ax.set_xticks(list(range(data_size.__len__())))
    ax.set_xticklabels(data_size, rotation=60)
    ax.set_xlabel('# Cumulated Executed Jobs')
    ax.set_ylabel('Model\nUncertainty [ms]')
    final_th = 0.1
    count = 0
    min_u = IQRs_RMSE[0]
    min_local_u = IQRs_RMSE[0]
    stops = []
    for i in range(1, len(data_size)):
        r = (IQRs_RMSE[i] / min_local_u)
        if ((r > 1) or (IQRs_RMSE[i] > min_u)):
            pass
        elif ((1 - r) < final_th):
            pass
        else:
            print(i, data_size[i], '-> STOP!')
            count += 1
            stops.append({'iteration': i, 'data_size': data_size[i], 'uncertainty': IQRs_RMSE[i], 'uncertainty_std': IQRs_std[i], 'cost': np.sum(np.exp(results['iterations_results'][i]['train_labels']))})
            print('--------------------------------')
        min_u = min(IQRs_RMSE[:(i + 1)])
        min_local_u = min(IQRs_RMSE[(i - 1):(i + 1)])
    if (len(stops) == 0):
        stops.append({'iteration': (len(data_size) - 1), 'data_size': data_size[(len(data_size) - 1)], 'cost': np.sum(np.exp(results['iterations_results'][(len(data_size) - 1)]['train_labels']))})
    ax.errorbar([s['iteration'] for s in stops], [s['uncertainty'] for s in stops], color='red', label='Early stop', linewidth=0, marker='o')
    ax.legend()
    print(pd.DataFrame(stops))
    return ax
def show_uncertainty(results, show_errors=False):
    data_size = results['data_size']
    IQRs_RMSE = results['model_uncertainty']
    IQRs_RMSE = np.array([np.mean((np.exp(I['uncertainty_high']) - np.exp(I['uncertainty_low']))) for I in results['iterations_results']])
    IQRs_std = np.array([np.std((np.exp(I['uncertainty_high']) - np.exp(I['uncertainty_low']))) for I in results['iterations_results']])
    (fig, ax) = plt.subplots(figsize=(8, 2))
    if show_errors:
        ax.errorbar(np.arange(len(IQRs_RMSE)), IQRs_RMSE, yerr=IQRs_std, fmt='o', label='Uncertainty')
    else:
        ax.plot(IQRs_RMSE, marker='o', label='Uncertainty')
    ax.set_xticks(list(range(data_size.__len__())))
    ax.set_xticklabels(data_size, rotation=60)
    ax.set_xlabel('# Cumulated Executed Jobs')
    ax.set_ylabel('Model\nUncertainty [ms]')
    final_th = 0.1
    count = 0
    min_u = IQRs_RMSE[0]
    min_local_u = IQRs_RMSE[0]
    stops = []
    for i in range(1, len(data_size)):
        r = (IQRs_RMSE[i] / min_local_u)
        if ((r > 1) or (IQRs_RMSE[i] > min_u)):
            pass
        elif ((1 - r) < final_th):
            pass
        else:
            print(i, data_size[i], '-> STOP!')
            count += 1
            stops.append({'iteration': i, 'data_size': data_size[i], 'uncertainty': IQRs_RMSE[i], 'uncertainty_std': IQRs_std[i], 'cost': np.sum(np.exp(results['iterations_results'][i]['train_labels']))})
            print('--------------------------------')
        min_u = min(IQRs_RMSE[:(i + 1)])
        min_local_u = min(IQRs_RMSE[(i - 1):(i + 1)])
    if (len(stops) == 0):
        stops.append({'iteration': (len(data_size) - 1), 'data_size': data_size[(len(data_size) - 1)], 'cost': np.sum(np.exp(results['iterations_results'][(len(data_size) - 1)]['train_labels']))})
    ax.errorbar([s['iteration'] for s in stops], [s['uncertainty'] for s in stops], color='red', label='Early stop', linewidth=0, marker='o')
    ax.legend()
    print(pd.DataFrame(stops))
    return ax