Pandas, Bokeh, or using any plotting library for s

2019-09-15 16:21发布

I want to display seasonal snow data for the seasonal year from July 01 - June 30.

df = pd.DataFrame({'date1':['1954-03-20','1955-02-23','1956-01-01','1956-11-21','1958-01-07'],
               'date2':['1954-03-25','1955-02-26','1956-02-11','1956-11-30','1958-01-17']},
              index=['1954','1955','1956','1957','1958'])

It is an extension to my previous question Pandas: Visualizing Changes in Event Dates for Multiple Years using Bokeh or any other plotting library

Scott Boston, in his answer to my comment in that question, suggested using Range1D and modifyng the answer in How can I accomplish `set_xlim` or `set_ylim` in Bokeh?. It works for continuous scalars, but I couldn't get it to work with a discontinuous ranges like [182:366], [1:181].

Adding x_range=Range1d(182, 366) shows me the first half of the seasonal year, but I can't get the second half of the seasonal year (1, 181).

df['date2'] = pd.to_datetime(df['date2'])

df['date1'] = pd.to_datetime(df['date1'])

df=df.assign(date2_DOY=df.date2.dt.dayofyear)
df=df.assign(date1_DOY=df.date1.dt.dayofyear)

from bokeh.plotting import figure, show
from bokeh.io import output_notebook
from bokeh.models import FuncTickFormatter, FixedTicker
p1 = figure(plot_width=1000, plot_height=300,x_range=Range1d(180, 366))

p1.circle(df.date1_DOY,df.index, color='red', legend='Date1')
p1.circle(df.date2_DOY,df.index, color='green', legend='Date2')
p1.xaxis[0].ticker=FixedTicker(ticks=[1,32,60,91,121,152,182,213,244,274,305,335,366])
p1.xaxis.formatter = FuncTickFormatter(code="""
 var labels = {'1':'Jan',32:'Feb',60:'Mar',91:'Apr',121:'May',152:'Jun',182:'Jul',213:'Aug',244:'Sep',274:'Oct',305:'Nov',335:'Dec',366:'Jan'}
 return labels[tick];
""")
show(p1)

#(Code from Scott's answer to my previous question.)

1条回答
兄弟一词,经得起流年.
2楼-- · 2019-09-15 17:13
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

df = pd.DataFrame({'date1':['1954-03-20','1955-02-23','1956-01-01','1956-11-21','1958-01-07'],
               'date2':['1954-03-25','1955-02-26','1956-02-11','1956-11-30','1958-01-17']},
              index=['1954','1955','1956','1957','1958'])
df['date2'] = pd.to_datetime(df['date2'])

df['date1'] = pd.to_datetime(df['date1'])

Adjusted mapping day of year to axis starting with Jun 1st.

df['date2_DOY_map'] = np.where(df['date2'].dt.dayofyear<151,df['date2'].dt.dayofyear-151+365,df['date2'].dt.dayofyear-151)

df['date1_DOY_map'] = np.where(df['date1'].dt.dayofyear<151,df['date1'].dt.dayofyear-151+365,df['date1'].dt.dayofyear-151)

from bokeh.plotting import figure, show
from bokeh.io import output_notebook

Add Range1d import form bokeh.models

from bokeh.models import FuncTickFormatter, FixedTicker,Range1d
p1 = figure(plot_width=1000, plot_height=300,x_range=Range1d(1, 366))

p1.circle(df.date1_DOY_map,df.index, color='red', legend='Date1')
p1.circle(df.date2_DOY_map,df.index, color='green', legend='Date2')

Fixed x-ticks and labels to match Jun 1st start

p1.xaxis[0].ticker=FixedTicker(ticks=[1,31,62,93,123,154,184,215,246,274,305,335,366])
p1.xaxis.formatter = FuncTickFormatter(code="""
 var labels = {'1':'Jun',31:'Jul',62:'Aug',93:'Sep',123:'Oct',154:'Nov',184:'Dec',215:'Jan',246:'Feb',274:'Mar',305:'Apr',335:'May',366:'Jun'}
 return labels[tick];
""")
show(p1)

enter image description here

EDIT (oops I started on the wrong month above)

Pretty easy to fix, we just need to modify the x-axis mapping of dates and redo the ticks and lables.

Use 181 vs 151 because Jul 1st is the 181st day where June 1st was the 151st day.

df['date2_DOY_map'] = np.where(df['date2'].dt.dayofyear<181,df['date2'].dt.dayofyear-181+365,df['date2'].dt.dayofyear-181)

df['date1_DOY_map'] = np.where(df['date1'].dt.dayofyear<181,df['date1'].dt.dayofyear-181+365,df['date1'].dt.dayofyear-181)

p1.xaxis[0].ticker=FixedTicker(ticks=[1,32,63,93,124,154,185,216,244,275,305,336,366])
p1.xaxis.formatter = FuncTickFormatter(code="""
 var labels = {'1':'Jul',32:'Aug',63:'Sep',93:'Oct',124:'Nov',154:'Dec',185:'Jan',216:'Feb',244:'Mar',275:'Apr',305:'May',336:'Jun',366:'Jul'}
 return labels[tick];
""")
查看更多
登录 后发表回答