Home > Enterprise >  Make joyplot/ridgeline plot using dates as the x-axis
Make joyplot/ridgeline plot using dates as the x-axis

Time:07-22

I am plotting a joyplot where the x-axis is a range of dates. However, joyplot only accepts dates arguments as numbers... As a result, the chart is plotted correctly, but the x-axis displays dates as their serial number, which is not very friendly to the end user.

I have tried various methods to format the axis (like this one: enter image description here

CodePudding user response:

I managed to get the dates in the x-axis with help from the link you provided. I wanted to go through it in a bit of detail here.

Code for reading and formatting data

As joyplot only takes numbers, I converted the strings (Jan2, 2018 format) to dates and put them in Date column. Then to numbers using ordinal. I mention this because the numbers above are slightly different. It should not matter...

import joypy
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt

%matplotlib inline

df = pd.read_excel('example.xlsx') ## Copy pasted data into excel
df['Date'] = pd.to_datetime(df['Release Date'], format = '%b %d, %Y')
df['Date_Number'] = df['Date'].apply(lambda x:x.toordinal())

Create array to be used for axis

This is similar to what was in the other SO post. But, the data was from some time in 1991 to 2023. So, hardcoded them. Used 9 ticks as I thought that the 32 years would blend well having 8 interim labels. Also, used -12 so that just the year and month would show up. I think as all are Jan, you can remove that as well. Will leave it up to you...

# Generate date strings from a manually set start date
numdays = 9
start_date = "01-Jan-1991"
dates = pd.date_range(start = "01-Jan-1991", end ='01-Jan-2023',periods=numdays)
dates = [str(date)[:-12] for date in dates]

Plot graph and adjust the axis

As in the other post, used ax[-1] to get the last axis. But do note that I have used the set_ticks() to get the ticks, then the set_ticklables() for the labels and finally the xlim() to set the ends of the start and end points, like so...

fig, ax = joypy.joyplot(df,  by = 'Distributor', column='Date_Number', 
                        colormap=matplotlib.cm.autumn, figsize = (10,6), fade = True)

ax[-1].set_xticks(range(numdays))
ax[-1].set_xticklabels(dates)
ax[-1].set_xlim([0, 8])

...and the resulting plot is

enter image description here

CodePudding user response:

First, please accept that the x-axis tick values in my answer may not be correct; it is unclear what the value obtained by ax[-1].get_xticks() indicates. Assuming it represents days, I can change it to a date in the following way: since the time series in maplotlib is Gregorian standard, I convert it from a number to a date.

df['Release Date'] = pd.to_datetime(df['Release Date'], format='%b %d, %Y')

import joypy
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
from matplotlib import cm
import matplotlib.dates as mdates
%matplotlib inline

fig, ax = joypy.joyplot(df, 
                        by = 'Distributor', 
                        column='Date', 
                        colormap=cm.autumn, 
                        figsize = (10,6),
                        xrot=45,
                        fade = True)

print(ax[-1].get_xticks())
new_dates = [mdates.num2date(x    mdates.date2num(np.datetime64('1900-01-01'))) for x in ax[-1].get_xticks()]
new_dates = [t.strftime('%b-%Y') for t in new_dates]
ax[-1].set_xticklabels(new_dates)

fig.show()

enter image description here

  • Related