Pandas, Bokeh, or using any plotting library for shifting the x-axis for seasonal data (months 7 -> 12 -> 6 or July 01 - June 30)

柔情痞子 提交于 2019-12-12 03:57:02

问题


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:


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)

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];
""")


来源:https://stackoverflow.com/questions/43727271/pandas-bokeh-or-using-any-plotting-library-for-shifting-the-x-axis-for-seasona

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!