How do I plot a series in Lilaq with a marker only on the last point?

As per this earlier question, I want to have a marker only on the very last point in a timeseries. I know that I can place text, but how do I get a marker on only the last point? I have tried by putting none everwhere else but the last point in the array, but lq.plot gives an error that it was expecting a float, and got none. Is there a null value of some kind that it will ignore and just pass on to the next point?

Or is there just a better way to achieve this?

For reference here is what I’m looking for:

Note how the last point is the only one with a marker in each series.

Here is my current code:

#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})

#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
    ),
    /* THIS DOES NOT WORK AS lq.plot does not accept "none"
    lq.plot(
      data.date,
      lastgold
    )
    */
  )
]

The goldidxs data can be found here.

EDIT

Bingo:

#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
#let gg = (data.gold.last(), )
#gg

#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
    )
  )
]


(I’ll worry about the colour mismatch later)

But is this the best way?

Hi, let me present to you two possible solutions. The first one is more general and applies to similar scenarios. The second one however is perfectly suited for your particular case.

Plotting the last value with a mark

The technique you tried is called masking and it is possible by setting coordinates to float.nan. This is mentioned in the first sentence of plot − Lilaq.

But here, you can plot just the last data point, no need to mask the input! This is also a bit better for performance.

// example data
#let x = range(10)
#let y1 = (1,4,5,7,3,6,8,5,3,2)
#let y2 = (6,4,7,3,2,5,6,8,9,4)

// Set cycle to just the first two colors of the default color cycle
// This way, the colors are repeated for the point plots. 
#show: lq.set-diagram(
  cycle: lq.color.map.petroff10.slice(0, 2)
)

#lq.diagram(
  lq.plot(x, y1, mark: none),
  lq.plot(x, y2, mark: none),
  lq.plot((x.last(),), (y1.last(),)),
  lq.plot((x.last(),), (y2.last(),)),
)

The color matching issue can of course be solved by setting lq.plot(.., color: ..) but much better is the solution above where the color cycle is effectively shortened to two entries which repeat after the first two line plots.

These are all idiomatic techniques when using Lilaq but now on to the second solution.

Using plot.every

Actually is is much easier! For this exact use case, there is the parameter plot.every which allows to render marks only on some points while the line is drawn through all points.

Here we only want to draw the point with the last index.

#lq.diagram(
  lq.plot(x, y1, every: (x.len() - 1,)),
  lq.plot(x, y2, every: (x.len() - 1,)),  
)