JuliaPlots / PlotlyJS.jl

Julia library for plotting with plotly.js
Other
413 stars 78 forks source link

Time series plot with period data type #474

Open WolfgangWeiss opened 8 months ago

WolfgangWeiss commented 8 months ago

Plotting time series with the data type Date works as expected

df1 = DataFrame(a=Date[Date("2023-10-20"), Date("2023-10-21"), Date("2023-10-22"), Date("2023-10-23")], b=Int[1, 2, 3, 2])
p1 = plot(df1, x=:a, y=:b)

Result: plot-1

But when using a Period data type such as Millisecond, Day, CompoundPeriod, ... the plot will appear blank

df2 = DataFrame(b=Millisecond[Millisecond(1000), Millisecond(2000), Millisecond(3000), Millisecond(4000)], a=Int[1, 2, 3, 2])
p2 = plot(df2, x=:a, y=:b)
startDate = Day(0)
df3 = DataFrame(b=Dates.CompoundPeriod[Dates.CompoundPeriod(startDate), Dates.CompoundPeriod(startDate + Day(1)), Dates.CompoundPeriod(startDate + Day(2)),Dates.CompoundPeriod(startDate + Day(3))], a=Int[1, 2, 3, 2])
p3 = plot(df3, x=:a, y=:b)

Result: plot-2

Version info

julia> versioninfo()
Julia Version 1.9.3
Commit bed2cd540a (2023-08-24 14:43 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Windows (x86_64-w64-mingw32)
  CPU: 8 × Intel(R) Core(TM) i7-3770 CPU @ 3.40GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-14.0.6 (ORCJIT, ivybridge)
  Threads: 1 on 8 virtual cores
Environment:
  JULIA_EDITOR = code
  JULIA_NUM_THREADS =
julia> using Pkg; pkg"status"
Status `... .julia\environments\v1.9\Project.toml`
  [336ed68f] CSV v0.10.11
  [a93c6f00] DataFrames v1.6.1
  [864edb3b] DataStructures v0.18.15
  [f0f68f2c] PlotlyJS v0.18.11
  [2913bbd2] StatsBase v0.34.2
  [fdbf4ff8] XLSX v0.10.0
jd-foster commented 8 months ago

This is not an issue with PlotlyJS precisely but with the dependency JSON.jl : it doesn't have a method to create a simple type (string or number) from the more complicated Dates.Period or Dates.CompoundPeriod types, while supporting the Dates.TimeType.

The question essentially reduces to how JSON.lower(v::T) should be defined for the two types. We can't properly define these methods without committing type piracy. There is a proper way described here: https://github.com/JuliaIO/JSON.jl#customizing-json . However, one might be tempted to just write PlotlyJS.JSON.lower(v::Dates.CompoundPeriod) = string(v) and PlotlyJS.JSON.lower(v::Dates.Period) = string(v) and still remain consistent with the implementation for Dates.TimeType.