# Histogram of dates in Plots.jl

I’ve come across this problem many times, but I can’t find any mentions of it anywhere on here or the Plots repo. Consider:

``````julia> using Plots

julia> histogram(rand(Date(2000, 1, 1):Day(1):Date(2001, 1, 1), 100))
``````

Here, Plots uses `Dates.value(date)` on the x-axis, which means one has to be pretty good at mental arithmetic to interpret what the graph actually shows. I’ve tried using `xformatter = x -> string(Date(0) + Day(x))` but to no avail (yes, I’ve also forgotten which function gives a `Date` from the `Dates.value` of a date, something I asked Jacob a long time ago on Slack…)

Are there issues related to this that I’ve missed? And does anybody have an idea for a workaround?

Relatedly, I just realized that `histogram` entirely ignores `xformatter` and `yformatter` kwargs:

``````julia> histogram(rand(1_000:2_000, 100), yformatter = x -> x/1_000)
``````

but

``````julia> plot(rand(1_000:2_000, 100), yformatter = x -> x/1_000)
``````

This seems to work (no bells and whistles):

``````using Dates, Plots; gr()

d1, d2 = Date(2000, 1, 1),  Date(2001, 1, 1)
d = rand(d1:Day(1):d2, 100)
de = Dates.date2epochdays.(d)
xb = range(Dates.date2epochdays(d1), stop = Dates.date2epochdays(d2), length=5)
xd = Dates.epochdays2date.(round.(Int,xb))

histogram(de, bins = xb, xticks=false, label="Dates histogram")
plot!(xticks=(xb,xd), ylims=(0,40))
``````

1 Like

Thanks, although it is of course severly limiting if one has to specify bins manually…

If one knows the exact algorithm used by `histogram()`, one could set the manual value in workaround above equal to the automatic value.
This could be obtained from a command like:

``````nbins = length(fit(Histogram,de).edges[1]) - 1
``````

Actually I’ve found an easier workaround: while `histogram` ignores formatters, they can be added to an existing histogram if it is plotted again. So:

``````plot(histogram(rand(Date(2000, 1, 1):Day(1):Date(2001, 1, 1), 100)),
xformatter = x -> Dates.epochdays2date(x+365))
``````

(Thanks for reminding me of the epochdays2date function!)

2 Likes

@nilshg, could you please verify the plot posted as the dates displayed run back to 1998 while the input data are from 2000 onward.

Indeed - it looks as though `Dates.value` is offset by one year from the `epochdays2date`

``````julia> Dates.value(Date(2000, 1, 1))
730120

julia> Dates.epochdays2date(730120)
1999-01-01
``````

so above one needs `Dates.epochdays2date(x+365)` to get the right answer

1 Like

I’m pretty sure I ran into this offset by 1 year issue quite a while ago. I ended up defining a conversion function that adjusted by the 1 year at the time.

That code has long since gone by the wayside.