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.
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
#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]
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.
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.
# 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