Change plotly hovertext dimensions - r

I am using plotly with r. I am using hovertext but need to change the dimensions of the hovertext box.
Here is my data:
my_data <-
structure(
list(
flood_freq = "none",
count = 111L,
acres = 213698L,
coiids = "632879, 632880, 633192, 633643, 633647, 634220, 634252, 2517005, 2517018, 2630129, 2630149, 2630150, 635379, 632879, 632880, 2517005, 635629, 635631, 2517005, 2517018, 2630129, 2630149, 2630150, 2630203, 2630207, 2630215, 2528971, 2406001, 2719494, 2719503, 2719504, 634220, 2517005, 2517018, 2630149, 2630150, 1423710, 2630203, 2630207, 1472815, 1472823, 2630215, 2528971, 2630207, 2406001, 635796, 635797, 635798, 635799, 635803, 635804, 635862, 635864, 635865, 635867, 635868, 635870, 635871, 635917, 635947, 635948, 635949, 635950, 635984, 635985, 635986, 635987, 635988, 635989, 635990, 635997, 636005, 636008, 636095, 636097, 636099, 636119, 636120, 636121, 637182, 637183, 637184, 637196, 637230, 637232, 637259, 637260, 637473, 637475, 637477, 637479, 2719494, 2719503, 2719504, 637647, 637649, 637652, 637657, 637667, 637821, 637944, 637945, 637946, 637947, 637949, 638073, 638160, 638161, 638216, 638217, 638218"
),
class = c("tbl_df", "tbl", "data.frame"),
row.names = c(NA, -1L)
)
I make a plotly barplot with the coiids as the hovertext.
plotly::plot_ly(
x = my_data$flood_freq,
y = my_data$count,
name = "Flood freq.",
type = "bar",
hoverinfo = "text",
hovertext = paste("coiids: ", my_data$coiids)
)
The hovertext of my concatenated coiids is long and gets cut off by the screen width.
How can I change the dimensions of the hovertext box to give it a constained width and greater height so that all of the coiids can be read?

One option would be to wrap your hover text using e.g. stringr::str_wrap:
library(plotly)
plot_ly(
x = my_data$flood_freq, y = my_data$count,
name = "Flood freq.", type = "bar",
hoverinfo = "text",
hovertext = paste("coiids: ", stringr::str_wrap(my_data$coiids, 60))
)

Related

How to configure thousand separator for hovertext in R plotly?

It looks like a simple task, but after hours looking aroung I'm not able to find a suitable solution.
I'm using plotly to plot line and bar charts, and I have trouble formatting hover numbers.
I want the following :
decimal separator ','
thousand separator ' '
I'm able to setup the decimal separator by setting the locale to FR. I'm also able to get space separator for the ticklabeld.
However I'm not able at all to add space as thousand separator.
I would like to find an elegant solution by setting hovertemplate = '%{x} | %{y:.0f}' , but any other solution would fit.
This is the code for my plot :
data <- EMPL1019[,c(1,2,4)]
colnames(data) <- c('Date','Salaries','Equivalent')
ticklabels <- seq(from=0, to=round(max(data$Salaries)), by=5000)
ticktexts <- c(0,paste(ticklabels[-1]/1000, " 000", sep=""))
EMP.g1 <- plot_ly(data = data,
name = 'Salariés',
line = list(color = ispfPalette[1]),
x = ~Date,
y = ~Salaries,
hovertemplate = '%{x} | %{y:.0f}<extra></extra>',
type = 'scatter',
mode = 'line')
EMP.g1 <- EMP.g1 %>% add_trace(y = ~Equivalent,
hovertemplate = '%{x} - %{y:.2f}<extra></extra>',
name = 'Equ. temps plein',
line = list(color = ispfPalette[9]))
EMP.g1 <- EMP.g1 %>% layout(yaxis = list(separatethousands = T,tickformat = '.0f'))
EMP.g1 <- EMP.g1 %>% layout(yaxis=list(tickvals = ticklabels,
ticktext = ticktexts))
EMP.g1 <- EMP.g1 %>% layout(yaxis = yaxis_template,
xaxis = xaxis_template,
legend = list(orientation = 'h'))
EMP.g1 <- EMP.g1 %>% config(locale = 'fr')
And this is a sample of my data :
structure(list(Date = structure(c(1635724800, 1633046400, 1630454400,
1627776000, 1625097600, 1622505600, 1619827200, 1617235200, 1614556800,
1612137600, 1609459200, 1606780800, 1604188800, 1601510400, 1598918400,
1596240000, 1593561600, 1590969600, 1588291200, 1585699200, 1583020800,
1580515200, 1577836800, 1575158400), class = c("POSIXct", "POSIXt"
), tzone = "UTC"), `Nombre de salariés` = c(67124L, 66347L,
65629L, 66937L, 66503L, 65780L, 64963L, 64820L, 64320L, 63978L,
64320L, 65139L, 64726L, 64824L, 64349L, 64252L, 63802L, 63302L,
60612L, 58449L, 66069L, 66680L, 66934L, 67530L), `Masse salariale` = structure(c(0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000938992338891789,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000909115204071465,
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000088773284923459,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000896660284134519,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000906967890625601,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000916330649236409,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000889642613151166,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000854022123447163,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000855530315648643,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000848916147880622,
0.00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008974157736486,
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110317720806686,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000870705472791466,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000859874685909506,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000857318642824282,
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000085576196400845,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000840277121133498,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000843657217346959,
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000082555304014476,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000801471849889434,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000900019006376449,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000904107403400091,
0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000979945565570618,
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000116166151318982
), class = "integer64"), `Effectif équivalent temps plein` = c(58126.7732710957,
57206.3988279215, 55259.2352879171, 55479.1570677117, 56688.511680619,
55841.9537494603, 54526.0767610181, 53368.5979797748, 53134.6513287857,
52946.3782282233, 53251.3191244597, 54829.7587531314, 53915.6804815763,
54306.2860265348, 54170.5949118788, 53649.4815305165, 52445.0726773908,
51356.6072581076, 50193.6687158648, 48360.6793136537, 56294.0759669762,
57709.3582162786, 57246.9744898572, 58543.1814151947)), class = c("data.table",
"data.frame"), row.names = c(NA, -24L), .internal.selfref = <pointer: 0x000001d4019765b0>)
I can't trust that there is no easy way to do it. Even tickvals and ticktext solution looks overcomplex and I'm sure there is a better way to do it.
Thanks in advance for your help !
It works, but it's not native Plotly. What I did was add the parameter hovertext, I then used this to format the values you used in y = Salaries and y = Equivalent. Then I replaced y in your hovertemplate with hovertext.
(I've only commented out the palettes because I don't have the data for these objects.)
EMP.g1 <- plot_ly(data = data,
name = 'Salariés',
line = list(color = 'darkred'), #ispfPalette[1]),
x = ~Date,
y = ~Salaries,
hovertext = ~formatC(Salaries, big.mark = " ",
format = "d"), # integer (no decimal)
hovertemplate = '%{x} | %{hovertext}<extra></extra>',
type = 'scatter',
mode = 'line')
EMP.g1 <- EMP.g1 %>%
add_trace(y = ~Equivalent,
hovertext = ~formatC(Equivalent,
big.mark = " ", # space separator
format = "d"), # integer (no decimal)
hovertemplate = '%{x} - %{hovertext}<extra></extra>',
name = 'Equ. temps plein',
line = list(color = 'black')) #ispfPalette[9]))
The rest of your code is unchanged.

Avoid ordering hoverinfo by group when using legendgroup in plotly

I have build a Gantt chart in plotly as per example.
I want to use trace filtering with plotly legend, but the code creates an enormous amount of traces which results in hundreds of traces in legend as well. To avoid that - I first use add_lines() on one row per each group with parameter showlegend = T and by specifying legendgroup. After that, I add the remaining lines to the figure with showlegend = F and by specifying the same legendgroup. This works great for the problem, but it messes the text flow inside hoverinfo. Namely, it groups and orders the text by legendgroup instead of allowing them to be ordered by xaxis value.
Data (an excerpt from Soderberg's Sex, Lies & Videotape :)):
library(plotly)
library(dplyr)
df_plotly = structure(list(tt = 1:9, speaker = c("A", "T", "A", "T", "A",
"T", "A", "T", "A"), min_time = c(42.328, 50.67, 53.297, 79.073,
87.54, 116.569, 120.948, 122.45, 131.959), max_time = c(50.5,
55.67, 81.573, 86.203, 112.938, 121.569, 125.948, 130.413, 136.959
), line = c("</br> Garbage.</br>All I've been thinking about all week is garbage.</br>I mean, I can't stop thinking about it.",
"</br> What kind of thoughts about garbage?", "</br> I just</br>I've gotten real concerned over what's gonna happen with all the garbage.</br>I mean, we've got so much of it.</br>You know? I mean, we have to run out of places to put this stuff eventually.</br>The last time I .</br>I started feelin' this way is when that barge was stranded</br>and, you know, it was going around the island and nobody would claim it.</br>Do you remember that?",
"</br> Yes, I remember.</br>Do you have any idea what may have triggered this concern?",
"</br> Yeah. Yeah.</br>You see, the other night, John was taking out the garbage,</br>and he kept spilling things out of the container,</br>and that made me</br>I started imagining, like,</br>a garbage can that produces garbage, and it doesn't stop.</br>It just keeps producing garbage, and it just keeps overflowing.</br>And, yy-you know, what would you do, you know, to try to stop something like that?",
"</br> Ann, do you see any pattern here?", "</br> What do you mean?",
"</br> Well, last week we were talking about your obsession</br>with the families of airline fatalities.</br>Now we're talking about your concern over the garbage problem.",
"</br> Yeah? So?"), color = structure(c(1L, 2L, 1L, 2L, 1L, 2L,
1L, 2L, 1L), .Label = c("#66C2A5", "#FC8D62"), class = "factor")), row.names = c(NA,
-9L), class = c("tbl_df", "tbl", "data.frame"))
Gantt without legend with correct order inside hoverinfo.
fig = plot_ly() %>% layout(hovermode = "x unified")
for(i in 1:(nrow(df_plotly) - 1)){
df =
df_plotly
fig <- add_lines(fig,
x = c(df$min_time[i], df$max_time[i]), # x0, x1
y = c(df$speaker[i], df$speaker[i]), # y0, y1
name = df$speaker[i],
mode = "lines",
line = list(color = df$color[i], width = 20),
hoverinfo = "text",
text = df$line[i],
evaluate = T # needed to avoid lazy loading
)
}
fig
Gantt with legend but with incorrect order inside hoverinfo:
fig = plot_ly() %>% layout(hovermode = "x unified")
for(i in 1:2){
df =
df_plotly %>%
group_by(speaker) %>%
filter(min_time == min(min_time)) %>%
ungroup()
fig <- add_lines(fig,
x = c(df$min_time[i], df$max_time[i]), # x0, x1
y = c(df$speaker[i], df$speaker[i]), # y0, y1
name = df$speaker[i],
mode = "lines",
line = list(color = df$color[i], width = 20),
legendgroup = df$speaker[i],
showlegend = T,
hoverinfo = "text",
text = df$line[i],
evaluate = T # needed to avoid lazy loading
)
}
for(i in 1:(nrow(df_plotly) - 1)){
df =
df_plotly %>%
group_by(speaker) %>%
filter(min_time != min(min_time)) %>%
ungroup()
fig <- add_lines(fig,
x = c(df$min_time[i], df$max_time[i]), # x0, x1
y = c(df$speaker[i], df$speaker[i]), # y0, y1
name = df$speaker[i],
mode = "lines",
line = list(color = df$color[i], width = 20),
legendgroup = df$speaker[i],
showlegend = F,
hoverinfo = "text",
text = df$line[i],
evaluate = T # needed to avoid lazy loading
)
}
fig
Thanks!

Calendar Heatmap in R

Looking to create a gt/reactable table in R that serves as a calendar heatmap. Something just like the one found on this site https://glin.github.io/reactable/articles/cookbook/cookbook.html. When I try to replicate that code, I get an error: "only defined on a data frame with all numeric-alike variables." I made Year a factor variable and do not want to color that column. Here is the code I tried + the dput output:
BuYlRd <- function(x) rgb(colorRamp(c("#7fb7d7", "#ffffbf", "#fc8d59"))
(x), maxColorValue = 255)
reactable(
bls,
defaultColDef = colDef(
style = function(value) {
if (!is.numeric(value)) return()
normalized <- (value - min(bls)) / (max(bls) - min(bls))
color <- BuYlRd(normalized)
list(background = color)
},
format = colFormat(digits = 2),
minWidth = 50
),
columns = list(
.rownames = colDef(name = "Year", sortable = TRUE, align =
"left")
),
bordered = TRUE
)
dput(head(bls))
structure(list(year = structure(1:3, .Label = c("2018", "2019",
"2020"), class = "factor"), January = c(329.5, 329.6, 327.5),
February = c(354.4, 328.5, 323.7), March = c(354.4, 324,
324.9), April = c(348.7, 326.9, 319.8), May = c(340.2, 321,
320.7), June = c(338, 316.1, 320.4), July = c(342.3, 317.3,
319), August = c(346.8, 317.3, 317.2), September = c(344.9,
317.3, 317), October = c(342.4, 318.2, 317.3), November =
c(334.4,
317.3, 328.2), December = c(335.5, 317.4, 328.7)), row.names =
c(NA,
-3L), class = c("tbl_df", "tbl", "data.frame"))
A solution could be to put the year column into the rownames of your dataset, and removing the year column thereafter :
bls=as.data.frame(bls)
rownames(bls)=bls$year
bls=bls[,-1]
reactable(
bls,
defaultColDef = colDef(
style = function(value) {
if (!is.numeric(value)) return()
normalized <- (value - min(bls)) / (max(bls) - min(bls))
color <- BuYlRd(normalized)
list(background = color)
},
format = colFormat(digits = 2),
minWidth = 50
),
columns = list(
.rownames = colDef(name = "Year", sortable = TRUE, align =
"left")
),
bordered = TRUE
)

Plotly barcharts with POSIXct and daylight-savings-time

I want to plot a barchart timeseries with timestamps on the x-axis. My problem is the daylight-saving in Octobre, as there are 2 timestamps at 02:00, one with CEST timezone and one with CET.
The plotly-barchart superimposes these values, which is hard to spot and looks like an error when you hover over the barchart as you will find that the value does not correspond to the y-axis.
How can I display these 2 bars side by side, without changing the tickmode to "array" and defining tickvals/ticktext?
library(plotly)
df <- structure(list(value = round(runif(46, 20, 26), 3),
timestamp = structure(c(1603576800, 1603584000, 1603587600, 1603591200, 1603594800, 1603598400,
1603602000, 1603605600, 1603609200, 1603612800, 1603616400, 1603620000,
1603623600, 1603627200, 1603630800, 1603634400, 1603638000, 1603641600,
1603645200, 1603648800, 1603652400, 1603656000, 1603659600, 1603576800,
1603584000, 1603587600, 1603591200, 1603594800, 1603598400, 1603602000,
1603605600, 1603609200, 1603612800, 1603616400, 1603620000, 1603623600,
1603627200, 1603630800, 1603634400, 1603638000, 1603641600, 1603645200,
1603648800, 1603652400, 1603656000, 1603659600),
class = c("POSIXct", "POSIXt"), tzone = "Europe/Berlin"),
col = c(rep("#FFBA00", 23), rep("#B9CC2E", 23)),
name = c(rep("Grp1", 23), rep("Grp2", 23))),
row.names = 1:46, class = "data.frame")
plot_ly(data = df, text = "text") %>%
add_trace(x = ~timestamp, y = ~value, type = "bar",
marker = list(color = ~col),
text = ~sprintf("Time: %s<br>Value: %s", timestamp, value),
hoverinfo = "text",
name = ~name) %>%
plotly::layout(xaxis = list(title = 'Time', type = "date"),
barmode = 'group')
Wraping up my comments to an answer for future readers:
plotly currently doesn't support displaying daylight saving time natively:
Changes our internal date linearization to use UTC rather than local
milliseconds. Every day on a Plotly graph will now be 24 hours long,
with no daylight shifts.
source: https://github.com/plotly/plotly.js/pull/1194#issue-95087563
Accordingly, the only possibility I'm aware of, to work around this issue is using the tickvals and ticktext arguments in plotly's layout function (not desired by #SeGa and this is reasonable as we'll have duplicated tick labels. Nevertheless, maybe the following helps others).
library(plotly)
DF <- structure(list(value = round(runif(46, 20, 26), 3),
timestamp = structure(c(1603576800, 1603584000, 1603587600, 1603591200, 1603594800, 1603598400,
1603602000, 1603605600, 1603609200, 1603612800, 1603616400, 1603620000,
1603623600, 1603627200, 1603630800, 1603634400, 1603638000, 1603641600,
1603645200, 1603648800, 1603652400, 1603656000, 1603659600, 1603576800,
1603584000, 1603587600, 1603591200, 1603594800, 1603598400, 1603602000,
1603605600, 1603609200, 1603612800, 1603616400, 1603620000, 1603623600,
1603627200, 1603630800, 1603634400, 1603638000, 1603641600, 1603645200,
1603648800, 1603652400, 1603656000, 1603659600),
class = c("POSIXct", "POSIXt"), tzone = "Europe/Berlin"),
col = c(rep("#FFBA00", 23), rep("#B9CC2E", 23)),
name = c(rep("Grp1", 23), rep("Grp2", 23))),
row.names = 1:46, class = "data.frame")
# DF$timestamp_utc <- DF$timestamp
# attr(DF$timestamp_utc, "tzone") <- "UTC"
plot_ly(data = DF, text = "text") %>%
add_trace(x = ~as.numeric(timestamp), y = ~value, type = "bar",
marker = list(color = ~col),
text = ~sprintf("Time: %s<br>Value: %s", timestamp, value),
hoverinfo = "text",
name = ~name) %>%
plotly::layout(xaxis = list(title = 'Time',
ticktext = ~timestamp,
tickvals = ~as.numeric(timestamp),
tickmode = "array"),
barmode = 'group')
Minor edit: If we want to reduce the amount of ticklabels without a lot of effort we can use pretty in ticktext and tickvals:
ticktext = ~pretty(timestamp),
tickvals = ~as.numeric(pretty(timestamp))
Related docs: Formatting Ticks in R

R Leaflet - use date or character legend labels with colorNumeric() palette

I have a dataset with lat/lon and a timestamp. I want the color of the markers to show time with a continous palette. I am using colorNumeric() with julian dates earlier created using julian(x, "2015-01-01").
data = structure(list(timestamp = structure(c(1434056453, 1434148216, 1434153635, 1434245436, 1434358840,
1434364288, 1434369611, 1434461435, 1434466830, 1434558725), class = c("POSIXct", "POSIXt"), tzone = ""),
lon = c(-119.8777, -119.9614, -119.8769, -119.8775, -120.2283,
-120.2285, -119.8429, -120.0954, -120.3957, -120.4421),
lat = c(34.4041,34.376, 34.4061, 34.4021, 34.4696,
34.4697, 34.1909, 34.4328, 34.4554, 34.4456),
ID = as.factor(c("Z11","Z05","Z01", "Z04", "Z11", "Z04","Z01","Z05","Z05","Z11"))),
.Names = c("timestamp", "lon", "lat", "ID"),
row.names = c(1:10),
class = "data.frame")
data$julian = as.numeric(julian(data$timestamp, origin = "2015-01-01"))
pal = colorNumeric( palette = rainbow(7), domain = data$julian)
m = leaflet(data)
m %>% addTiles() %>%
addCircles(~lon, ~lat, color = ~pal(julian)) %>%
addLegend("bottomright", pal = pal, values = ~julian, title = "Time", opacity = 1)
The legend shows the labels as numeric, julian dates: I want them to show as "proper" dates in a format like "2015-01-01" or similar.
To do this, I use as.Date(x, origin=as.Date("2015-01-01")) but it does not work when I insert it into addLegend() with addLegend(pal = pal, values = ~julian,
labFormat = labelFormat(transform = ~as.Date(julian, origin=as.Date("2015-01-01"))))
Is there a way to modify legend labels so that they show dates and/or characters?
From the leaflet page on legends:
You can also conveniently customize the label appearance by passing labFormat=labelFormat(). labelFormat() has parameters that customize the separator between ranges, the number of digits to render, and prefix/suffix for each label. If your label formatting needs extend beyond what labelFormat() can provide, you can also use a custom function as the labFormat argument; see the Details section in ?addLegend for a description.
Therefore, we can modify the source code for the labelFormat function to include a custom function to convert dates
myLabelFormat = function(
prefix = '', suffix = '', between = ' – ', digits = 3, big.mark = ',',
transform = identity, dates = FALSE ## new 'dates' argument
) {
formatNum = function(x) {
format(
round(transform(x), digits), trim = TRUE, scientific = FALSE,
big.mark = big.mark
)
}
## added 'formatDate' function
formatDate = function(x) {
d = as.Date(x, origin="1970-01-01")
}
function(type, ...) {
switch(
type,
numeric = (function(cuts) {
if(dates){
## will format numbers into dates if dates == TRUE
paste0(formatDate(cuts))
}else{
paste0(prefix, formatNum(cuts), suffix)
}
})(...),
bin = (function(cuts) {
n = length(cuts)
paste0(prefix, formatNum(cuts[-n]), between, formatNum(cuts[-1]), suffix)
})(...),
quantile = (function(cuts, p) {
n = length(cuts)
p = paste0(round(p * 100), '%')
cuts = paste0(formatNum(cuts[-n]), between, formatNum(cuts[-1]))
# mouse over the legend labels to see the values (quantiles)
paste0(
'<span title="', cuts, '">', prefix, p[-n], between, p[-1], suffix,
'</span>'
)
})(...),
factor = (function(cuts) {
paste0(prefix, as.character(transform(cuts)), suffix)
})(...)
)
}
}
Which, as #Nice points out can be shortened to
myLabelFormat = function(...,dates=FALSE){
if(dates){
function(type = "numeric", cuts){
as.Date(cuts, origin="1970-01-01")
}
}else{
labelFormat(...)
}
}
With this new function we can call it as normal
data = structure(list(timestamp = structure(c(1434056453, 1434148216, 1434153635, 1434245436, 1434358840,
1434364288, 1434369611, 1434461435, 1434466830, 1434558725), class = c("POSIXct", "POSIXt"), tzone = ""),
lon = c(-119.8777, -119.9614, -119.8769, -119.8775, -120.2283,
-120.2285, -119.8429, -120.0954, -120.3957, -120.4421),
lat = c(34.4041,34.376, 34.4061, 34.4021, 34.4696,
34.4697, 34.1909, 34.4328, 34.4554, 34.4456),
ID = as.factor(c("Z11","Z05","Z01", "Z04", "Z11", "Z04","Z01","Z05","Z05","Z11"))),
.Names = c("timestamp", "lon", "lat", "ID"),
row.names = c(1:10),
class = "data.frame")
data$julian <- as.numeric(as.Date(data$timestamp))
library(leaflet)
pal = colorNumeric( palette = rainbow(7), domain = data$julian)
m = leaflet(data)
m %>% addTiles() %>%
addCircles(~lon, ~lat, color = ~pal(julian)) %>%
addLegend("bottomright", pal = pal, values = ~julian,
title = "Time", opacity = 1,
labFormat = myLabelFormat(dates=TRUE))

Resources