2016-07-29 9 views
2

Ich habe eine Grafik, die mit Hilfe von Datetime-Objekten für die x-Achse geplottet wurde und ich möchte in der Lage sein, unterhalb der Grafik selbst (die y-Werte) und der x-Achse. Ich fand diesen Post Matplotlib's fill_between doesnt work with plot_date, any alternatives?, der ein ähnliches Problem beschreibt, aber die vorgeschlagenen Lösungen halfen mir überhaupt nicht.Farbe zwischen der X-Achse und der Grafik in PyPlot

Mein 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 

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

UZTWC = np.genfromtxt(data_file, 
          delimiter=',', 
          names=columns, 
          skip_header=1, 
          usecols=("UZTWC")) 

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

dates = matplotlib.dates.date2num(list_of_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() 

Dies ergibt:

Traceback (most recent call last): 
    File "test_color.py", line 36, in <module> 
    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'' 

Es scheint, das Problem kommt mit fill_between meine Daten in der Lage zu handhaben ist vom Typ 'numpy.ndarray'. Muss ich das einfach in einen anderen Datentyp konvertieren, damit dies funktioniert?

EDIT: Nach mehr Tests, habe ich festgestellt, dass ich immer noch genau diesen Fehler erhalten, auch nach dem Versuch, list_of_datetimes zu verwenden, und nach dem Konvertieren aller meiner Zeitangaben in Zeitstempeln, so beginne ich mich zu fragen, ob es ein Typ ist Ausgabe immerhin.

Beispieldaten:

%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 

Ich bin mit Python 3.5.0 und 1.5.1 matplotlib auf 10 Fenster und ich gewann alle meine Abhängigkeiten durch WinPython https://sourceforge.net/projects/winpython/

+0

Ich glaube, das ist die Art von Fehlermeldung, die Sie bekommen, wenn Sie 'np.nan' in dort haben ... – bernie

+0

Könnten Sie bitte klären? Wenn es hilft, funktioniert dieser Code ohne fill_between ohne Fehler –

+0

Könnten Sie ein kleines Beispiel vorbereiten, das das Problem aufweist? Ohne irgendwelche sensiblen Daten, wenn Sie das haben? – bernie

Antwort

1

ich habe noch was zu bestimmen, ging in Ihrem ursprünglichen Code falsch, aber ich habe es mit pandas arbeiten:

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