SveltePlot Details
Pascal Schmidt
2025-04-21
SveltePlotDetails.Rmd
Line Charts and Time-Series
Adding Multiple Series
We’ll plot a line chart with the gapminder
data. Note
that we need to drop the levels when plotting individual countries. This
is due to the fact that SveltePlots
expects us to provide
the number of colors equal to the number of levels in the column for the
color mapping. So we can either drop the extra levels or coerce the
column into a character vector.
In the chart below, we added 3 additional series for the the
countries Chile and Germany. We specify group = country
for
the legend to display the country name.
data("gapminder")
gapminder <- gapminder |>
dplyr::mutate(
country = as.character(country),
year = lubridate::ymd(paste0(year, "-01-01"))
)
sp <- SveltePlots::sp(
data = gapminder |>
dplyr::group_by(year, continent) |>
dplyr::summarise(
lifeExp = mean(lifeExp)
) |>
dplyr::ungroup(),
mapping = spaes(x = year, y = lifeExp, group = continent),
type = "line",
combine_same_groups = FALSE
) |>
sp_add_series(
data = gapminder |>
dplyr::filter(country == "Germany"),
mapping = spaes(x = year, y = lifeExp, group = country),
type = "line",
colors = "gold"
) |>
sp_add_series(
gapminder |>
dplyr::filter(country == "Chile"),
mapping = spaes(x = year, y = lifeExp, group = country),
type = "line",
colors = "silver"
) |>
sp_add_series(
gapminder |>
dplyr::filter(country == "Chile"),
mapping = spaes(x = year, y = lifeExp, group = country),
type = "points",
size = 3,
tooltip = FALSE
)
We can add a title with sp_title()
sp |>
sp_title(
title = "Life Expectancy Over Time",
font_size = 26
)
For the above graph we added a points series and a line series for
Chile and both series show up in the legend because of
combine_same_groups = FALSE
in the sp
function. We do not show the tooltip for the points series for
Chile.
Legends and Hovering
By clicking the legend, we can add and remove series. Sometimes, it
is nice to control multiple series that correspond to the same groups
with one click. By default, SveltePlots
uses only one
legend to control all series for the same group. Different from the
gapminder chart above where we had
combine_same_groups = FALSE
, in this chart we have
combine_same_groups = TRUE
, which is the default. This
combines different line and points series into one legend entry.
sp(
data = purchases,
type = "line",
mapping = spaes(x = date, y = revenue_roll, group = age),
colors = c("red", "green", "blue"),
combine_same_groups = TRUE
) |>
sp_add_series(
data = purchases,
mapping = spaes(x = date, y = revenue, group = age),
type = "points",
alpha = 0.4
) |>
sp_add_series(
data = purchases[purchases$revenue == max(purchases$revenue), ],
mapping = spaes(x = date, y = revenue, group = age),
type = "points",
size = 5,
tooltip = F
)
The line and points, which are two different series, are controlled by one legend entry.
Similarly, we can also control each series we are plotting with the
legend by specifying combine_same_groups = FALSE
. Then we
can add and remove each series individually.
sp <- sp(
data = purchases,
mapping = spaes(x = date, y = revenue_roll, group = age),
type = "line",
colors = c("red", "green", "blue"),
combine_same_groups = FALSE
) |>
sp_add_series(
data = purchases,
mapping = spaes(x = date, y = revenue, group = age),
type = "points",
alpha = 0.4,
tooltip = F,
) |>
sp_add_series(
data = purchases[purchases$revenue == max(purchases$revenue), ],
mapping = spaes(x = date, y = revenue, group = age),
type = "points",
size = 5,
tooltip = F,
include_legend = F
)
sp
We also removed the legend with include_legend = F
for
the last series.
Below is another example with the mtcars data set where we would like
to highlight points which have greater or equal to 28 miles per gallon.
In this case we should choose combine_same_groups = FALSE
to have control over both series with the two legend entries.
data("mtcars")
sp <- sp(
mtcars |> dplyr::filter(mpg < 28),
mapping = spaes(x = mpg, y = wt),
type = "points",
colors = "black",
combine_same_groups = FALSE
) |>
sp_add_series(
data = mtcars |>
dplyr::filter(mpg >= 28),
mapping = spaes(x = mpg, y = wt),
type = "points",
size = 5,
colors = "red"
)
sp
Line Breaks
We can combine lines when we are not having any NA
values in the data set.
set.seed(123)
purchases_line_breaks <- purchases[sample(1:nrow(purchases), size = nrow(purchases)*0.7), ]
sp <- sp(
data = purchases_line_breaks,
mapping = spaes(x = date, y = revenue_roll, group = age),
type = "line",
colors = c("red", "green", "blue")
) |>
sp_add_series(
data = purchases_line_breaks,
mapping = spaes(x = date, y = revenue_roll, group = age),
type = "points",
tooltip = F
)
sp
Similarly, we can break lines when having NA values in the data set for the y-values. Notice, when there are no two consecutive dates, there will not be a line and therefore, we added a points series as well.
purchases_line_breaks <- purchases
purchases_line_breaks$revenue_roll[sample(1:nrow(purchases), size = nrow(purchases)*0.2)] <- NA
sp <- sp(
data = purchases_line_breaks,
mapping = spaes(x = date, y = revenue_roll, group = age),
type = "line",
colors = c("red", "green", "blue")
) |>
sp_add_series(
data = purchases_line_breaks,
mapping = spaes(x = date, y = revenue_roll, group = age),
type = "points",
tooltip = F
)
sp
Confidence Intervals
We can specify confidence intervals or bands with the
y_min
and y_max
arguments in the
spaes
function.
data("confidence_intervals")
sp(
data = confidence_intervals,
mapping = spaes(x = .index, y = .value, group = .key),
type = "line",
size = 2
) |>
sp_add_series(
data = confidence_intervals |>
dplyr::mutate(.key = as.character(.key)) |>
na.omit(),
mapping = spaes(x = .index, y_min = .conf_lo, y_max = .conf_hi, group = .key),
type = "bands"
)
Facetting
When we want to create multiple charts based on a column or multiple
columns in the data, we need to specify the faceting variable in the
sp()
function with the facet_var
argument. It
takes the name of a column as a character or a character vector of
multiple columns which present in the data set. In the
sp_facet()
function, we can specify how many rows and
column we want. By default, the scales are fixed and can be change to be
free as well. The sp_facet
function should always be the
last funtion used in the chain.
data("penguins")
sp <- sp(
data = penguins,
mapping = spaes(x = flipper_length_mm, y = bill_length_mm, group = species),
type = "points",
facet_var = "sex"
) |>
SveltePlots::sp_facet(ncol = 2, scales = "free")
sp
The levels or groups in the columns will be the facet titles of the
charts. We can customize them with some custom css for the header.
Again, make sure that the sp_facet()
function is the last
function in the chain.
custom_css_titles <- "background-color: grey; color: white;
text-align: center; padding: 10px;
border-radius: 5px;"
sp <- sp(
data = penguins,
mapping = spaes(x = flipper_length_mm, y = bill_length_mm),
type = "points",
facet_var = c("sex", "species"),
include_legend = FALSE
) |>
sp_x_axis(rotation_axis_ticks = -90) |>
sp_title(custom_css = custom_css_titles) |>
SveltePlots::sp_facet(scales = "fixed")
sp
Annotations
We can add annotations with the sp_add_segments
,
sp_add_arrows
, and sp_add_text
functions. The
sp_add_segments
function automatically adds a legend to the
chart which we can click. If we do, there is a popup which we can drag
around on the chart. That becomes useful if there are multiple segments
on the chart whoich are overlapping and we would like to drag them into
certain positions. A double click will make the popups disappear
again.
data("purchases")
sp(
data = purchases, type = "line",
mapping = spaes(x = date, y = revenue_roll, group = age),
colors = c("red", "green", "blue"),
combine_same_groups = TRUE
) |>
sp_add_series(
data = purchases,
mapping = spaes(x = date, y = revenue, group = age),
type = "points",
alpha = 0.4,
tooltip = F,
include_legend = F
) |>
sp_add_series(
data = purchases[purchases$revenue == max(purchases$revenue), ],
mapping = spaes(x = date, y = revenue, group = age),
type = "points",
size = 5,
tooltip = F
) |>
sp_add_segments(
x_start = "2000-01-12", x_end = "2000-01-17",
y_start = "auto", y_end ="auto",
type = "rect",
opacity = 0.2,
background_color = "black",
text_color = "white",
show_legend = TRUE,
legend_text = "Highest Revenue Day",
tooltip = "Revenue: <strong>$13179</strong>"
) |>
sp_add_arrows(
x_start = c("2000-03-01", "2000-03-01"), x_end = c("2000-01-15", "2000-01-15"),
y_start = c(8000, 12000), y_end = c(10000, 13000),
arrow_head = c(0, 0),
size = c(200, 200),
curvature = c(0.2, 0.4),
direction = c("downward", "downward"),
color = c("black", "black"),
arrow_head_type = c("triangle", "triangle")
) |>
sp_add_text(
x = c("2000-02-01", "2000-02-20"),
y = c(12500, 8500),
text = c(
"This was the highest revenue day",
"Window of Some Event Happening"
)
)
Segments
If we click on the letter I, we can see a lot more popups which we can drag around on the chart to see to which event they correspnd to.
#> # A tibble: 6 × 6
#> event_type start_date end_date extra_details colors key
#> <chr> <date> <date> <chr> <chr> <dbl>
#> 1 a 2022-11-25 2022-11-29 Some Extra Details About the Ev… #8c56… 1
#> 2 a 2022-12-16 2022-12-30 Some Extra Details About the Ev… #8c56… 2
#> 3 a 2023-02-15 2023-03-01 Some Extra Details About the Ev… #8c56… 3
#> 4 b 2023-05-29 2023-06-21 Some Extra Details About the Ev… #1f77… 4
#> 5 c 2023-05-30 2023-06-01 Some Extra Details About the Ev… #98df… 5
#> 6 d 2023-05-31 2023-07-04 Some Extra Details About the Ev… #2ca0… 6
sp <- sp(
data = dau,
type = "line",
spaes(x = date, y = DAU),
tooltip = FALSE
) |>
sp_add_series(
data = dau,
mapping = spaes(x = date, y = DAU),
type = "points",
size = 4,
tooltip = TRUE,
) |>
sp_add_segments(
x_start = segments$start_date,
x_end = segments$end_date,
y_start = "even",
y_end = "even",
type = "rect",
opacity = 0.2,
background_color = segments$colors,
text_color = "white",
show_legend = TRUE,
legend_text = segments$event_type,
tooltip = unlist(segments$extra_details),
key = segments$key
) |>
sp_title("DAU", font_size = 24) |>
sp_x_axis(rotation_axis_ticks = -30)
sp
Custom Tooltip
The custom tooltip works if we have a list column of tibbles named
custom_tooltip
. The chart will recognize the name and will
use this column to create custom tooltips instead of using the y
variable, retention in this case, for the tooltip. The column names for
the individual tibbles will be displayed as the keys with the
corresponding values.
data("quests")
quests <- quests |>
dplyr::rowwise() |>
dplyr::mutate(
custom_tooltip = dplyr::tibble(
Installs = n.y,
`Quest Start` = n.x,
Retention = as.character(round(retention, 4)*100)
) |> list()
) |>
dplyr::ungroup()
head(quests)
#> # A tibble: 6 × 6
#> AB n.x n.y retention level custom_tooltip
#> <chr> <dbl> <dbl> <dbl> <fct> <list>
#> 1 a 25814 83435 0.309 1 <tibble [1 × 3]>
#> 2 b 25638 82929 0.309 1 <tibble [1 × 3]>
#> 3 b 18204 82929 0.220 49 <tibble [1 × 3]>
#> 4 a 17652 83435 0.212 49 <tibble [1 × 3]>
#> 5 b 16939 82929 0.204 11 <tibble [1 × 3]>
#> 6 a 16839 83435 0.202 11 <tibble [1 × 3]>
Some More Examples With Different Data Sets
Walmart
The Walmart weekly sales data displays weekly revenue by department. We added points and lines series and a mix of manually added colors for department 1 and 3 and default colors for the other departments. We also rotated the x-axis and changed the labels for the y-axis to have aa dollar format. If you would like to explore the different formats which can be used you can check out the documentation.
data("walmart_sales_weekly")
walmart_sales_weekly <- walmart_sales_weekly |>
dplyr::select(Dept, Date, Weekly_Sales) |>
dplyr::arrange(Date) |>
dplyr::as_tibble() |>
dplyr::mutate(
Date = lubridate::ymd(Date)
)
sp(
data = walmart_sales_weekly |>
dplyr::filter(Dept %in% c(1, 3)),
mapping = spaes(x = Date, y = Weekly_Sales, group = Dept),
type = "line",
colors = c("black", "grey")
) |>
sp_add_series(
data = walmart_sales_weekly |>
dplyr::filter(Dept %in% c(38, 93, 95)),
mapping = spaes(x = Date, y = Weekly_Sales, group = Dept),
type = "line"
) |>
sp_add_series(
data = walmart_sales_weekly |>
dplyr::filter(Dept %in% c(8, 13)),
mapping = spaes(x = Date, y = Weekly_Sales, group = Dept),
type = "points"
) |>
sp_x_axis(rotation_axis_ticks = -30) |>
sp_y_axis(format = "$,.3r")
CO2 Data
The charts below show case time-series data with adjustments for tooltips and axis.
data("CO2")
CO2 <- CO2 |>
dplyr::as_tibble() |>
dplyr::mutate(
date = seq(
as.Date("2023-01-01"),
as.Date("2023-01-01") + lubridate::days(83), by = "day")
)
sp(
data = CO2, type = "line",
mapping = spaes(x = date, y = uptake, group = Type)
) |>
sp_add_series(
data = CO2,
mapping = spaes(x = date, y = conc, group = Type),
type = "line", tooltip = F
) |>
sp_add_series(
data = CO2, mapping =
spaes(x = date, y = conc, group = Type),
type = "points"
) |>
sp_x_axis(format = "%b-%d")
Economics
data("economics")
sp(
data = economics,
mapping = spaes(x = date, y = unemploy),
type = "line",
tooltip = T,
colors = "red"
) |>
sp_add_series(
data = economics,
mapping = spaes(x = date, y = pce),
type = "line",
tooltip = T,
colors = "green"
) |>
sp_add_series(
data = economics,
mapping = spaes(x = date, y = psavert),
type = "line",
tooltip = F,
colors = "blue"
) |>
sp_x_axis(
format = "%b %Y",
ticks = 4,
label = "Date",
font_size_label = 14,
font_size_ticks = 12,
rotation_axis_ticks = -30
) |>
sp_y_axis(
font_size_label = 14,
font_size_ticks = 12
)
Hourly Time-Series
The chart below shows hourly data with a rotation of the x-axis tick labels.
# Generate hourly time series data for 7 days
set.seed(123)
start_time <- as.POSIXct("2022-01-01 00:00:00")
end_time <- start_time + 1 * 24 * 3600 # 7 days in seconds
timestamps <- seq(start_time, end_time, by = "hour")
values <- rnorm(length(timestamps)) # Random values for demonstration purposes
# Create a tibble
hourly_tibble <- tibble(
timestamp = timestamps,
value = values
)
sp(
data = hourly_tibble,
mapping = spaes(x = timestamp, y = value),
type = "line",
include_legend = FALSE
) |>
sp_x_axis(
label = "Date",
rotation_axis_ticks = 90,
text_anchor = "end"
)