[PYTHON] matplotlib Schreiben Sie Text in ein Zeitreihendiagramm

Einführung

Ich habe ein Zeitreihendiagramm erstellt, bin jedoch auf die Methode zum Anzeigen von Text an der angegebenen Position gestoßen und habe es überprüft, damit ich es hochladen kann. Unsere Umgebung ist wie folgt. Die Arbeit wird am Juputer-Notizbuch erledigt.

Beispiel

fig_test.png

Wo ich es mir ausgedacht habe

In der im Beispiel gezeigten Grafik wird die fehlende Periode der Durchflussdaten grau ausgefüllt und die Periode im Text angezeigt. Die Textanzeige dieser fehlenden Periode ist das Highlight dieses Beitrags.

Bezüglich der Achseneinstellung des Zeitreihendiagramms folge ich dem folgenden Artikel, den ich zuvor gepostet habe.

https://qiita.com/damyarou/items/19f19658b618fd05b3b6

So zeigen Sie Text in einem Zeitreihendiagramm an

Erstellen Sie eine Zeichenfolgenliste mit den Start- und Endpunkten des fehlenden Zeitraums und konvertieren Sie sie in den Datums- / Uhrzeittyp

    #Beginn der Daten ohne Entladung (Beginn der fehlenden Periode)
    _sss=['2014-10-29',
          '2014-12-01',
          '2017-08-01',
          '2018-01-01',
          '2018-06-01',
          '2019-06-01']
    #Ende ohne Entladungsdaten
    _sse=['2014-10-31',
          '2014-12-31',
          '2017-12-31',
          '2018-04-30',
          '2018-08-31',
          '2019-12-31']
    sss=[]
    sse=[]
    for ss,se in zip(_sss,_sse):
        ss = datetime.datetime.strptime(ss, '%Y-%m-%d')
        se = datetime.datetime.strptime(se, '%Y-%m-%d')
        sss=sss+[ss]
        sse=sse+[se]

Füllen Sie die erforderlichen Teile mit Grau und zeigen Sie den Text an, während Sie die Schleife für jede fehlende Periode drehen

        for ss,se in zip(sss,sse):
            xx=dates.date2num(ss)+(dates.date2num(se)-dates.date2num(ss))/2 #Geben Sie die mittlere x-Koordinate der Textanzeigeposition an
            x1=dates.date2num(xmin) #Der x-Koordinaten-Startpunkt des Diagramms
            x2=dates.date2num(xmax) #X-Koordinaten-Endpunkt des Diagramms
            if x1<xx<x2: #Textzeichnung, wenn sich die Position der Textanzeige zwischen dem Start- und dem Endpunkt des Diagramms befindet
                plt.axvspan(ss,se,color='#cccccc')
                xs=dates.num2date(xx)
                ys=ymin+0.3*(ymax-ymin)
                tstr1 = ss.strftime('%Y/%m/%d')
                tstr2 = se.strftime('%Y/%m/%d')
                sstr=tstr1+'~'+tstr2+'\nno discharge data'        
                plt.text(xs,ys,sstr,ha='center',va='bottom',fontsize=fsz,rotation=90,linespacing=1.5)

Das Ausfüllen von Grau erfolgt mit `` `axvspan```.

Um die Position der Textanzeige festzulegen, setzen Sie `matplotlib.dates importieren als Datum``` und` date.date2num () `(ab Mitternacht + 1 am 1. Januar 1 n. Chr.) Ich benutze die Funktionen (Tage in Gleitkomma konvertieren) und date.num2date () (Gleitkomma in datetime``` konvertieren).

Im Programm werden jedes Jahr mehrere Jahre lang ähnliche Diagramme erstellt, sodass "der Start- und Endpunkt der x-Achse für jedes Diagramm überprüft und nur gezeichnet wird, wenn die Position der Textanzeige dazwischen liegt". Wenn Sie dies nicht tun, wird der Text an einer lächerlichen Stelle angezeigt. So wird es gemacht.

Der Text wird mit einem `plt.text ()` über zwei Zeilen ausgegeben. Dieser Zeilenabstand wird durch `` `Zeilenabstand = 1.5``` eingestellt.

Funktionen siehe unten.

Ich bin mir bewusst, aber ich tue es nicht

Wenn Sie sich das Diagramm genau ansehen, sehen Sie, dass für einen Tag vor und nach dem fehlenden Zeitraum Ende Oktober und vor dem fehlenden Zeitraum im Dezember ein Leerzeichen vorhanden ist. Dies liegt daran, dass die Uhrzeit des in den Daten angegebenen Datums Mitternacht des Tages ist, sodass der Zeitraum von Mitternacht bis 24:00 Uhr des Tages nicht ausgefüllt bleibt. Da es sich bei den Plotdaten um Tagesdaten handelt, sollten sie mit "bar" gefüllt werden, das Zeichnen dauert jedoch sehr lange. Daher ist es gut, sie mit "fill_between" zu füllen.

Volles Programm

# Time series drawing
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import datetime
import matplotlib.dates as dates
import matplotlib.dates as mdates


def inp_rf():
    fnameR='xls_rdata_20190630.xlsx'
    df = pd.read_excel(fnameR,index_col=0)
    df.index = pd.to_datetime(df.index, format='%Y/%m/%d')
    df_rf=df['2013/01/01':'2019/12/31']
    return df_rf


def inp_qq():
    fnameR='df_qq1.csv'
    df = pd.read_csv(fnameR,index_col=0)
    df.index = pd.to_datetime(df.index, format='%Y/%m/%d')
    df_qq=df['2013/01/01':'2019/12/31']
    return df_qq

    
def drawfig(df_rf,df_qq):
    # start of no discharge data
    _sss=['2014-10-29',
          '2014-12-01',
          '2017-08-01',
          '2018-01-01',
          '2018-06-01',
          '2019-06-01']
    # end of no discharge data
    _sse=['2014-10-31',
          '2014-12-31',
          '2017-12-31',
          '2018-04-30',
          '2018-08-31',
          '2019-12-31']
    sss=[]
    sse=[]
    for ss,se in zip(_sss,_sse):
        ss = datetime.datetime.strptime(ss, '%Y-%m-%d')
        se = datetime.datetime.strptime(se, '%Y-%m-%d')
        sss=sss+[ss]
        sse=sse+[se]
    yyyy=np.array([2013,2014,2015,2016,2017,2018,2019])
    fsz=12
    st='01-01'
    ed='12-31'
    for year in yyyy:
        sxmin=str(year)+'-'+st
        sxmax=str(year)+'-'+ed
        plt.figure(figsize=(16,6),facecolor='w')
        plt.rcParams['font.size']=fsz
        xmin = datetime.datetime.strptime(sxmin, '%Y-%m-%d')
        xmax = datetime.datetime.strptime(sxmax, '%Y-%m-%d')
        ymin=0
        ymax=400
        plt.xlim([xmin,xmax])
        plt.ylim([ymin,ymax])
        sxlabel='Date ({0})'.format(year)
        plt.xlabel(sxlabel)
        plt.ylabel('Daily discharge Q (m$^3$/s)')
        plt.grid(which='major',axis='both',color='#999999',linestyle='--')
        for ss,se in zip(sss,sse):
            xx=dates.date2num(ss)+(dates.date2num(se)-dates.date2num(ss))/2
            x1=dates.date2num(xmin)
            x2=dates.date2num(xmax)
            if x1<xx<x2:
                plt.axvspan(ss,se,color='#cccccc')
                xs=dates.num2date(xx)
                ys=ymin+0.3*(ymax-ymin)
                tstr1 = ss.strftime('%Y/%m/%d')
                tstr2 = se.strftime('%Y/%m/%d')
                sstr=tstr1+'~'+tstr2+'\nno discharge data'        
                plt.text(xs,ys,sstr,ha='center',va='bottom',fontsize=fsz,rotation=90,linespacing=1.5)

        plt.fill_between(df_qq.index,df_qq['q_tot'],0,color='#ff00ff',label='Q (total)')
        plt.fill_between(df_qq.index,df_qq['q_lll']+df_qq['q_rrr'],0,color='#00ff00',label='Q (Right)')
        plt.fill_between(df_qq.index,df_qq['q_lll'],0,color='#ff0000',label='Q (Left)')
        plt.twinx()
        plt.ylim([ymax,ymin])
        plt.ylabel('Daily rainfall RF (mm/day)')
        plt.fill_between(df_rf.index,df_rf['RF'],0,color='#0000ff',label='RF in basin by JWA')
        plt.fill_between([0],[0],0,color='#ff00ff',label='Q (total)')
        plt.fill_between([0],[0],0,color='#00ff00',label='Q (Right)')
        plt.fill_between([0],[0],0,color='#ff0000',label='Q (Left)')
        plt.legend(bbox_to_anchor=(1, 1.01), loc='lower right', borderaxespad=0.1, ncol=4, shadow=True, fontsize=fsz-2)
    
        #plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d-%b-%Y'))
        plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d-%b'))
        plt.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=1))
        plt.gca().xaxis.set_minor_locator(mdates.MonthLocator(interval=1))
        plt.gcf().autofmt_xdate()

        fnameF='fig_'+str(year)+'.png'
        plt.savefig(fnameF, dpi=100, bbox_inches="tight", pad_inches=0.1)
        plt.show()


def main():
    df_rf=inp_rf()
    df_qq=inp_qq()
    drawfig(df_rf,df_qq)
    

#==============
# Execution
#==============
if __name__ == '__main__': main()

das ist alles

Recommended Posts

matplotlib Schreiben Sie Text in ein Zeitreihendiagramm
Zeitreihendiagramm / Matplotlib
Zeichnen Sie Zeitreihendaten in Python mit Pandas und Matplotlib
[Grafikzeichnung] Ich habe versucht, ein mehrreihiges Balkendiagramm mit Matplotlib und Seaborn zu schreiben
So vergleichen Sie Zeitreihendaten-Derivative DTW, DTW-
So zeichnen Sie ein Diagramm mit Matplotlib
Umgang mit Zeitreihendaten (Implementierung)
So vermeiden Sie, dass Sie jedes Mal% matplotlib inline schreiben
Zeitreihenzerlegung
Lesen von Zeitreihendaten in PyTorch
matplotlib graph album
[Python] Wie zeichnet man mit Matplotlib ein Liniendiagramm?
Python: Zeitreihenanalyse
Diagrammzeichnung mit matplotlib
Ich habe 10 Bücher gelesen, die sich auf Zeitreihendaten beziehen, daher werde ich eine Rezension schreiben.
Python-Zeitreihenfrage
RNN_LSTM1 Zeitreihenanalyse
Zeitreihenanalyse 1 Grundlagen
Banddiagramm mit Matplotlib
Wie benutzt man Matplotlib?
TOPIX-Zeitreihen anzeigen
Ich habe ein Paket erstellt, um Zeitreihen mit Python zu filtern
Herausforderung für die zukünftige Umsatzprognose: ② Zeitreihenanalyse mit PyFlux
Eine Lernmethode für Anfänger zum Erlernen der Zeitreihenanalyse
Formatieren Sie die Zeitachse des Pandas-Zeitreihendiagramms mit matplotlib neu
[Einführung in matplotlib] Lesen Sie die Endzeit aus den COVID-19-Daten ♬
Schreiben Sie Diagramme in Echtzeit mit Matplotlib auf dem Jupyter-Notizbuch
Herausforderung für die zukünftige Umsatzprognose: ⑤ Zeitreihenanalyse von Prophet