#!/usr/bin/python3
# -*- coding: utf-8 -*-
########################################################################
#
# This file is part of python module <pyspc>.
# Copyright (C) 2013-2021 R. Marty
# (renaud.marty@developpement-durable.gouv.fr)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program (see COPYING.txt).
# If not, see <http://www.gnu.org/licenses/>.
#
########################################################################
"""
Images - Forecast Verification
"""
import matplotlib.pyplot as plt
import pyspc.core.exception as _exception
from pyspc.plotting.colors import TABCOLORS
[docs]
def plot(filename=None, df=None, scen=None, ltime=None,
title=None, ytitle=None):
"""
Tracer les résultats de vérification de prévision.
Parameters
----------
filename : str
Fichier image à créer
df : pnd.DataFrame
Tableau de données
scen : str
Code scénario
ltime : int
Echéance de prévision "cible" du SPC
title : str
Titre de la figure
ytitle : str
Titre de l'axe Y
Returns
-------
filename : str
Fichier image créé
See Also
--------
pyspc.Series.errors
"""
_exception.check_str(filename)
# _exception.check_str(scen)
# _exception.check_int(ltime)
# _exception.check_str(title)
# _exception.check_str(ytitle)
# -------------------------------------------------------------------------
# 0- Initialisation
# -------------------------------------------------------------------------
# subplots = sorted({x for x in df.columns.get_level_values(level=0)})
subplots = sorted(set(df.columns.get_level_values(level=0)))
fig, axs = plt.subplots(
nrows=2,
ncols=int(len(subplots) / 2),
figsize=(11.69, 8.27),
dpi=150,
sharex=True,
sharey=True
)
axs = axs.flatten()
# -------------------------------------------------------------------------
# 1- Création de chaque subplot
# -------------------------------------------------------------------------
for ks, s in enumerate(subplots):
ax = axs[ks]
try:
ax.plot(df.index, df[(s, 'mean')], color='tab:blue',
linestyle='-.', label='moyenne')
ax.plot(df.index, df[(s, '50%')], color='tab:red',
linestyle='-', label='médiane')
ax.fill_between(df.index, df[(s, '10%')], df[(s, '90%')],
color='tab:orange', alpha=0.5, linewidth=0.5)
ax.plot(df.index, df[(s, '90%')], color='tab:orange',
linestyle='-', label='dernier décile', linewidth=0.5)
ax.plot(df.index, df[(s, '10%')], color='tab:orange',
linestyle='-', label='premier décile', linewidth=0.5)
except KeyError:
pass
if ks in [2, 3]:
ax.set_xlabel('Echéance [h]', fontsize=8)
ax.tick_params(axis='x', labelsize=8)
if ks in [0, 2]:
ax.set_ylabel(ytitle, fontsize=8)
ax.tick_params(axis='y', labelsize=8)
ax.grid(True, linewidth=0.3, color='darkgray', linestyle=':')
ax.set_title(f'{scen}-{s}',
color='tab:gray', fontweight='bold')
if ks == 3:
ax.legend(loc=0)
# for ks, ns in enumerate(subplots):
for ks, _ in enumerate(subplots):
ax = axs[ks]
try:
ylim = ax.get_ylim()
ax.plot([ltime, ltime], ylim, scalex=False, scaley=False,
linewidth=1, color='tab:brown')
ax.text(ltime+1, ylim[0], f'{ltime}h',
color='tab:brown', fontweight='bold',
verticalalignment='bottom', horizontalalignment='left')
except KeyError:
pass
# -------------------------------------------------------------------------
# 2- Titre et légende
# -------------------------------------------------------------------------
plt.suptitle(title, fontsize=12, fontweight='bold')
fig.tight_layout(rect=(0, 0, 1, 0.95))
plt.savefig(filename, dpi=150)
plt.close(fig)
return filename
[docs]
def plot_uncertainty(filename=None, df=None, ltime=None, title=None,
labels=None):
"""
Tracer les fréquences théoriques et observées des tendances.
Parameters
----------
filename : str
Fichier image à créer
df : pnd.DataFrame
Tableau de données
ltime : int
Echéance de prévision "cible" du SPC
title : str
Titre de la figure
labels : dict
Correspondance entre la tendance et le label de la courbe
Returns
-------
filename : str
Fichier image créé
See Also
--------
pyspc.Series.errors
"""
_exception.check_str(filename)
# _exception.check_int(ltime)
# _exception.check_str(title)
# _exception.check_dict(labels)
# -------------------------------------------------------------------------
# 0- Initialisation
# -------------------------------------------------------------------------
fig = plt.figure(dpi=150)
ax = fig.add_axes((0.10, 0.20, 0.87, 0.67))
# -------------------------------------------------------------------------
# 1- Création des courbes
# -------------------------------------------------------------------------
subplots = sorted(set(df.columns.get_level_values(level=0)))
targets = []
for s in subplots:
try:
t = int(s) / 100.
except TypeError:
t = None
else:
if t == 0:
t = None
targets.append(t)
for c, s, t in zip(TABCOLORS, subplots, targets):
try:
# La courbe réelle
ax.plot(df.index, df[(s, 'f+')], color=c,
linestyle='-', linewidth=2, label=labels.get(s, s))
# La courbe cible
if t is None:
continue
ax.plot([min(df.index), max(df.index)], [t, t], scalex=False,
linewidth=1, color=c, alpha=0.5,
label=f'Cible {int(100 * t):2d}%')
except ZeroDivisionError: # ax.get_xlim()
pass
# -------------------------------------------------------------------------
# 2- Titre et légende
# -------------------------------------------------------------------------
ax.set_ylim([0, 1])
ax.set_xlabel('Echéance [h]', fontsize=8)
ax.xaxis.set_tick_params(labelsize=8)
ax.set_ylabel('Fréquence [%]', fontsize=8)
ax.yaxis.set_tick_params(labelsize=8)
ax.grid(True, linewidth=0.3, color='darkgray', linestyle=':')
try:
ylim = ax.get_ylim()
ax.plot([ltime, ltime], ylim, scalex=False, scaley=False,
linewidth=1, color='tab:brown', label='délai cible')
ax.text(ltime+1, ylim[-1], f'{ltime}h',
color='tab:brown', fontweight='bold',
verticalalignment='bottom', horizontalalignment='left')
except KeyError:
pass
# Shrink current axis's height by 10% on the bottom
box = ax.get_position()
ax.set_position([box.x0, box.y0 + box.height * 0.05,
box.width, box.height * 0.95])
# Put a legend below current axis
ax.legend(loc='upper center', bbox_to_anchor=(0.5, -0.15), fontsize=8,
ncol=len(subplots))
plt.suptitle(title, fontsize=10, fontweight='bold')
plt.savefig(filename, dpi=150)
plt.close(fig)
return filename