How do I place text in a lilaq chart that contains a datetime axis?

In my previous question, I managed to plot a single point at the end of timeseries chart, but now I need to place a label next to it. If I give place actual numerics it works fine, but if the x-axis point is a datetime as per the chart, it refuses it (“Cannot subtract length from datetime”). See the bottom of the code below.

#set page(paper: "us-legal", columns: 1, margin: 1cm)
#import "@preview/lilaq:0.5.0" as lq

#let string-to-date(str) = toml(bytes("v=" + str)).v

#let data = lq.load-txt(
  read("goldidxs.csv"),
  converters: ("date": string-to-date),
  header: true,
)

#let arange = range(0, data.date.len()).rev()
#let rangegold = arange.zip(data.gold)
#let lastgold = rangegold.map(x => if x.at(0) == 0 {x.at(1)} else {none})
#let dd = (data.date.last(), )
#dd.at(0)
#let gg = (data.gold.last(), )
#gg.at(0)

#block[
  #lq.diagram(
    width: 10cm,
    height: 8cm,
    title: "gold",
    lq.plot(
      data.date, 
      data.gold,
      mark: none
    ),
    lq.plot(
      data.date,
      data.simple_gold,
      mark: none
    ),
    lq.plot(
      dd,
      gg,
      mark: "x"
    ),
    // this works
    lq.place(1, 1)["1234"]
    //this doesnt
    //lq.place(dd.at(0), gg.at(0))["hello"]
    //neither does this
    //lq.place(dd, gg)["hello"]
  )
]

Again goldidxs data is here

Current output is below, and I need to label the “x” with its y-axis numerical value.

Hi @Vegabook ,

unfortunately, lq.place does not accept datetime inputs as of Lilaq version 0.5.0. In the next version 0.6.0 (coming soon), this will be supported (it is already implemented).

Until then you can simulate this. Below I show how to reproduce the conversion of dates to float values as Lilaq does it internally.

#let x = range(10).map(i => datetime(year: 2000, month: 1, day: i+1))
#let y1 = (1,4,5,7,3,6,8,5,3,2)
#let y2 = (6,4,7,3,2,5,6,8,9,4)

// The same reference time that Lilaq uses
#let t0 = datetime(year: 0, month: 1, day: 1)

#lq.diagram(
  margin: (right: 20%),
  lq.plot(x, y1, every: (x.len() - 1,)),
  lq.plot(x, y2, every: (x.len() - 1,)),  
  lq.place(
    (x.last() - t0).seconds(), y1.last(), 
    align: left,
    pad(.5em)[A]
  ),
  lq.place(
    (x.last() - t0).seconds(), y2.last(), 
    align: left,
    pad(.5em)[B]
  ),
)

1 Like