Can I create a time series with a reverse-log axis scale, so more recent dates are wider apart?

Question:

In a few recent applications I have plotted some time series where the more recent values are of more interest, but the historical values are good for context. Here’s an example, a toy tracker for progress on a written project:

plot of progress on a dissertation

Ideally I would like the more recent dates to be shown more spread out on the x-axis, but still labelled correctly as dates. This would look a bit like a logarithmic scale in reverse. I think this idea might be quite useful for timelines in contexts where progress accelerates over time, e.g. computation power.

I’ve looked at this matplotlib "timeline" example for inspiration, but can’t quite see how to achieve the spacing and labelling I want.

Here is a minimal example to work with:

import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from io import StringIO

data = '''when,words
2019-11-11,537
2019-12-19,530
2020-03-16,876
2020-08-10,1488
2021-02-05,2222
2022-01-21,2839
2022-03-02,3050
2022-03-04,3296
2022-03-15,3370
2022-03-23,3575
2022-04-25,2711
2022-06-06,3014
2022-06-28,3130
'''

prog = pd.read_csv(StringIO(data), parse_dates=['when'])
fig, ax = plt.subplots(figsize=(6,6))
sns.lineplot(ax=ax,data=prog,x="when",y="words",markers=True,marker="o")
ax.set(ylim=(0,1.1*prog.words.max()),title="Dissertation Progress")
fig.autofmt_xdate()
fig.tight_layout()

Which produces:
enter image description here

Asked By: Mr Felix U

||

Answers:

You may try something along these lines, i.e. converting your dates to number of days and then applying np.log10() on them:

prog.loc[:,'days'] = -np.log10(abs((prog.when - prog.iloc[-1].when).dt.days - 100))
g = sns.lineplot(x="days",y="words",data=prog,markers=True,marker="o")
_ = g.set_xticks(prog.days.to_list(), prog.when.dt.date.to_list(), rotation=90)

This yields this plot:

enter image description here

You can then handle overlapping labels by manually adjusting the xticklabels.

Answered By: max_jump
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.