2 votes

Couleur entre l'axe des x et le graphique dans PyPlot

J'ai un graphique qui a été tracé en utilisant des objets datetime pour l'axe des x et je veux pouvoir colorier en dessous du graphique lui-même (les valeurs y) et l'axe des x. J'ai trouvé ce post Matplotlib's fill_between ne fonctionne pas avec plot_date, des alternatives ? décrivant un problème similaire, mais les solutions proposées ne m'ont pas du tout aidé.

Mon code :

import matplotlib.patches as mpatches
import matplotlib.dates
import matplotlib.pyplot as plt
import numpy as np
import csv
from tkinter import *
from datetime import datetime
from tkinter import ttk

colonnes = "YEAR,MONTH,DAY,HOUR,PREC,PET,Q,UZTWC,UZFWC,LZTWC,LZFPC,LZFSC,ADIMC,AET"
fichier_de_donnees = "FFANA_000.csv"

UZTWC  = np.genfromtxt(fichier_de_donnees, 
                            delimiter=',', 
                            names=colonnes, 
                            skip_header=1, 
                            usecols=("UZTWC"))

liste_de_datetimes = []
entete_omise = False;
with open(fichier_de_donnees, 'rt') as f:
    lecteur = csv.reader(f, delimiter=',', quoting=csv.QUOTE_NONE)
    for ligne in lecteur:
        if entete_omise:
            date_string = "%s/%s/%s %s" % (ligne[0].strip(), ligne[1].strip(), ligne[2].strip(), ligne[3].strip())
            dt = datetime.strptime(date_string, "%Y/%m/%d %H")
            liste_de_datetimes.append(dt)
        entete_omise = True

dates = matplotlib.dates.date2num(liste_de_datetimes)

fig = plt.figure(1)
#UZTWC
ax1 = fig.add_subplot(111)
plt.plot(dates, UZTWC, '-', color='b', lw=2)
ax1.fill_between(dates, 0, UZTWC)
fig.autofmt_xdate()
plt.title('UZTWC', fontsize=15)
plt.ylabel('MM', fontsize=10)
plt.tick_params(axis='both', which='major', labelsize=10)
plt.tick_params(axis='both', which='minor', labelsize=10)
plt.grid()

plt.show()

Cela donne :

Traceback (most recent call last):
  File "test_color.py", line 36, in 
    ax1.fill_between(dates, 0, UZTWC)
  File "C:\Users\rbanks\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\__init__.py", line 1812, in inner
    return func(ax, *args, **kwargs)
  File "C:\Users\rbanks\AppData\Local\Programs\Python\Python35-32\lib\site-packages\matplotlib\axes\_axes.py", line 4608, in fill_between
   y2 = ma.masked_invalid(self.convert_yunits(y2))
  File "C:\Users\rbanks\AppData\Local\Programs\Python\Python35-32\lib\site-packages\numpy\ma\core.py", line 2300, in masked_invalid
    condition = ~(np.isfinite(a))
TypeError: ufunc 'isfinite' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''

Il semble que le problème vient de fill_between qui ne peut pas gérer mes dates étant de type 'numpy.ndarray'. Dois-je juste convertir ceci en un autre type de données pour que cela fonctionne ?

MODIFIER : Après plus de tests, j'ai constaté que j'obtenais toujours cette erreur exacte même après avoir essayé d'utiliser liste_de_datetimes, et après avoir converti tous mes datetimes en timestamps, donc je commence à me demander s'il s'agit vraiment d'un problème de type.

Données échantillon :

%YEAR,MO,DAY,HR,PREC(MM/DT),ET(MM/DT),Q(CMS), UZTWC(MM),UZFWC(MM),LZTWC(MM),LZFPC(MM),LZFSC(MM),ADIMC(MM), ET(MM/DT)
2012,   5,   1,   0,     0.000,     1.250,     0.003,     2.928,     0.000,     3.335,     4.806,     0.000,     6.669,     1.042
2012,   5,   1,   6,     0.000,     1.250,     0.003,     2.449,     0.000,     3.156,     4.798,     0.000,     6.312,     0.987
2012,   5,   1,  12,     0.000,     1.250,     0.003,     2.048,     0.000,     2.970,     4.789,     0.000,     5.940,     0.929
2012,   5,   1,  18,     0.000,     1.250,     0.003,     1.713,     0.000,     2.782,     4.781,     0.000,     5.564,     0.869
2012,   5,   2,   0,     0.000,     1.250,     0.003,     1.433,     0.000,     2.596,     4.772,     0.000,     5.192,     0.809
2012,   5,   2,   6,     0.000,     1.250,     0.003,     1.199,     0.000,     2.414,     4.764,     0.000,     4.829,     0.750

J'utilise Python 3.5.0 et matplotlib 1.5.1 sur Windows 10 et j'ai obtenu toutes mes dépendances via WinPython https://sourceforge.net/projects/winpython/

1voto

bernie Points 44206

J'ai encore du mal à déterminer ce qui n'allait pas dans votre code original, mais j'ai réussi à le faire fonctionner avec pandas:

import pandas as pd, matplotlib.pyplot as plt, matplotlib.dates as mdates

df = pd.read_csv('/path/to/yourfile.csv')
df['date'] = df['%YEAR'].astype(str)+'/'+df['MO'].astype(str)+'/'+df['DAY'].astype(str)
df['date'] = pd.to_datetime(df['date'])
dates = [date.to_pydatetime() for date in df['date']]

yyyy_mm_dd_format = mdates.DateFormatter('%Y-%m-%d')

plt.clf()
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot_date(dates,df[' UZTWC(MM)'],'-',color='b',lw=2)
ax.fill_between(dates,0,df[' UZTWC(MM)'])
ax.xaxis.set_major_formatter(yyyy_mm_dd_format)
ax.set_xlim(min(dates), max(dates))
fig.autofmt_xdate()
plt.show()

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X