0

I want to create a plot where the y-axis is the number of seasonal years I have data for and the x-axis is in months and days. Each seasonal year will have two dates.

|1957|...
|1956|             d1--------d2
|1955|                                d1---------d2 
|1954|                                                    d1---------d2
     |June01|...|Jan01...|Feb11|...|Feb23|...|Feb26|...|Mar20|...|Mar25|..

Example data

I almost have the graph I want, except the x-axis covers the entire time span rather than just 12-months.

from bokeh.plotting import figure
p1 = figure(plot_width=1000, plot_height=300, x_axis_type="datetime")
p1.circle(merged.date1, merged.index, color = 'red', legend = 'Date1')
p1.circle(merged.date2, merged.index, color = 'green', legend = 'Date2')
show(p1)

Plot of Seasonal Year vs Year-Month-Day

I have been trying to strip the year from the date and still plot it as a date. The first line below works, but because of the leap years the second line returns an error in the real data (day is out of range for month). df_snw['Date1'] = df_snw['Date1'].map(lambda x: x.strftime('%m-%d')) df_snw = pd.to_datetime(df_snw['Date1'], format='%m-%d')

3
  • 1
    Instead of posting a screenshot of your data, please post code that generates a representative example dataset. See MCVE guidelines for help. Also, it would be helpful if you can explain the relationship between df_snw, merged (in the Bokeh code), and the screenshot you've posted. Commented May 1, 2017 at 3:32
  • 1
    The title of your post begins "Pandas plotting", and the link you provide uses Pandas for plotting, but it looks like you're trying to plot using Bokeh. Is it sufficient to demonstrate a solution using Pandas only? If not, consider updating the title and adding a note about this (aside from the bokeh tag) in your post. Commented May 1, 2017 at 3:34
  • Thanks Andrew for taking the time to point out how better ask my question. I have tried to clean it up following your pointers and I will keep them in mind going forward.
    – ma8
    Commented May 1, 2017 at 5:04

1 Answer 1

1

I would convert your date1 and date2 to day of the year for the xaxis and re-label the x ticks as the months. This way all the data is overlayed on a 1 to 365 xaxis scale.

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'])

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)

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)

enter image description here

3
  • Thanks Scott for your answer. Is it possible to shift the x-axis so that instead of starting Jan 01 and ending Dec 31, it starts Jul 01 and ends Jun 30. I tried rearranging the numbers in the ticks list, but that just shifts the labels.
    – ma8
    Commented May 1, 2017 at 9:03
  • 1
    You are going to use the Range1D method. See this SO post Commented May 1, 2017 at 13:52
  • Scott, I tried to use Range1D method, but I could only get it to work with continuous scalars. I posted this as a question because it is a separate issue from this one. stackoverflow.com/questions/43727271/…
    – ma8
    Commented May 1, 2017 at 22:14

Not the answer you're looking for? Browse other questions tagged or ask your own question.