library(rtemis.draw).:rtemis.draw 0.0.3 🖌 aarch64-apple-darwin20
Attaching package: 'rtemis.draw'
The following object is masked from 'package:graphics':
Axis
.:rtemis.draw 0.0.3 🖌 aarch64-apple-darwin20
Attaching package: 'rtemis.draw'
The following object is masked from 'package:graphics':
Axis
The draw_* functions (Tier 1) cover the most common chart types with a clean, data-first interface. When you need control over individual ECharts options — custom axis breaks, stacked series, dual y-axes, per-point colors, or anything else not exposed through Tier 1 — you work directly with the S7 classes (Tier 2).
The pattern is always the same:
LineSeries, BarSeries, ScatterSeries, …)Axis, Title, Legend, Tooltip, …)EChartsOptiondraw()'data.frame': 344 obs. of 8 variables:
$ species : Factor w/ 3 levels "Adelie","Chinstrap",..: 1 1 1 1 1 1 1 1 1 1 ...
$ island : Factor w/ 3 levels "Biscoe","Dream",..: 3 3 3 3 3 3 3 3 3 3 ...
$ bill_len : num 39.1 39.5 40.3 NA 36.7 39.3 38.9 39.2 34.1 42 ...
$ bill_dep : num 18.7 17.4 18 NA 19.3 20.6 17.8 19.6 18.1 20.2 ...
$ flipper_len: int 181 186 195 NA 193 190 181 195 193 190 ...
$ body_mass : int 3750 3800 3250 NA 3450 3650 3625 4675 3475 4250 ...
$ sex : Factor w/ 2 levels "female","male": 2 1 1 NA 1 2 1 2 NA NA ...
$ year : int 2007 2007 2007 2007 2007 2007 2007 2007 2007 2007 ...
BoxplotSeries expects data in [min, Q1, median, Q3, max] format. Use grDevices::boxplot.stats() to compute those values:
bs <- grDevices::boxplot.stats(na.omit(penguins$body_mass))$stats
draw(EChartsOption(
title = Title(text = "Body Mass"),
tooltip = Tooltip(trigger = "item"),
x_axis = Axis(type = "category", data = list("Body Mass")),
y_axis = Axis(type = "value", scale = TRUE),
series = BoxplotSeries(
data = list(bs),
item_style = ItemStyle(border_color = "red", color = "transparent")
)
))vars <- list(
`Bill Length` = penguins$bill_len,
`Bill Depth` = penguins$bill_dep,
`Flipper Length` = penguins$flipper_len
)
box_data <- lapply(vars, function(v) grDevices::boxplot.stats(na.omit(v))$stats)
draw(EChartsOption(
tooltip = Tooltip(trigger = "item"),
x_axis = Axis(type = "category", data = names(vars)),
y_axis = Axis(type = "value", scale = TRUE),
series = BoxplotSeries(data = box_data)
))One BoxplotSeries per group, each with its own ItemStyle:
groups <- levels(factor(penguins$species))
colors <- rtemis_colors[seq_along(groups)]
series <- lapply(seq_along(groups), function(i) {
vals <- na.omit(penguins$body_mass[penguins$species == groups[i]])
BoxplotSeries(
name = groups[i],
data = list(grDevices::boxplot.stats(vals)$stats),
item_style = ItemStyle(
color = adjustcolor(colors[i], alpha.f = 0.25),
border_color = colors[i]
)
)
})
draw(EChartsOption(
legend = Legend(),
tooltip = Tooltip(trigger = "item"),
x_axis = Axis(type = "category", data = list("Body Mass")),
y_axis = Axis(type = "value", scale = TRUE),
series = series
))Use graphics::hist() to compute bins, then pass counts to BarSeries:
Consistent break points across groups; one BarSeries per group:
breaks <- graphics::hist(na.omit(penguins$body_mass), plot = FALSE)$breaks
series <- lapply(levels(factor(penguins$species)), function(sp) {
hg <- graphics::hist(
na.omit(penguins$body_mass[penguins$species == sp]),
breaks = breaks, plot = FALSE
)
BarSeries(name = sp, data = hg$counts)
})
draw(EChartsOption(
legend = Legend(),
x_axis = Axis(type = "category", data = formatC(
graphics::hist(na.omit(penguins$body_mass), breaks = breaks, plot = FALSE)$mids,
format = "g"
)),
y_axis = Axis(type = "value"),
series = series
))stats::density() returns $x and $y; pass them as [x, y] pairs to LineSeries:
d <- stats::density(na.omit(penguins$body_mass))
draw(EChartsOption(
title = Title(text = "Body Mass"),
x_axis = Axis(type = "value", scale = TRUE),
y_axis = Axis(type = "value"),
series = LineSeries(
data = mapply(c, d$x, d$y, SIMPLIFY = FALSE),
show_symbol = FALSE,
area_style = AreaStyle(opacity = 0.25)
)
))groups <- levels(factor(penguins$species))
series <- lapply(groups, function(sp) {
d <- stats::density(na.omit(penguins$body_mass[penguins$species == sp]))
LineSeries(
name = sp,
data = mapply(c, d$x, d$y, SIMPLIFY = FALSE),
show_symbol = FALSE,
area_style = AreaStyle(opacity = 0.25)
)
})
draw(EChartsOption(
legend = Legend(),
x_axis = Axis(type = "value", scale = TRUE),
y_axis = Axis(type = "value"),
series = series
))Set the same stack string on every series to stack them:
year_species <- table(penguins$year, penguins$species)
years <- rownames(year_species)
groups <- colnames(year_species)
series <- lapply(groups, function(sp) {
BarSeries(name = sp, data = as.integer(year_species[, sp]), stack = "total")
})
draw(EChartsOption(
legend = Legend(),
x_axis = Axis(type = "category", data = years),
y_axis = Axis(type = "value"),
series = series
))Swap the axis types to produce horizontal bars:
Scatter data is a list of [x, y] vectors, produced conveniently with mapply:
dat <- mapply(c, penguins$bill_len, penguins$flipper_len, SIMPLIFY = FALSE)
dat <- dat[!sapply(dat, function(p) any(is.na(p)))] # drop NA pairs
draw(EChartsOption(
tooltip = Tooltip(trigger = "item"),
x_axis = Axis(type = "value", scale = TRUE),
y_axis = Axis(type = "value", scale = TRUE),
series = ScatterSeries(data = dat)
))groups <- levels(factor(penguins$species))
colors <- rtemis_colors[seq_along(groups)]
series <- lapply(seq_along(groups), function(i) {
sp <- groups[i]
idx <- penguins$species == sp & !is.na(penguins$bill_len) & !is.na(penguins$flipper_len)
dat <- mapply(c, penguins$bill_len[idx], penguins$flipper_len[idx], SIMPLIFY = FALSE)
ScatterSeries(
name = sp,
data = dat,
item_style = ItemStyle(color = colors[i])
)
})
draw(EChartsOption(
legend = Legend(),
tooltip = Tooltip(trigger = "item"),
x_axis = Axis(type = "value", scale = TRUE),
y_axis = Axis(type = "value", scale = TRUE),
series = series
))For numeric x, data is [x, y] pairs; for categorical x, data is y-values only with a category axis:
year_counts <- as.integer(table(penguins$year))
years <- sort(unique(penguins$year))
draw(EChartsOption(
title = Title(text = "Penguins Observed per Year"),
x_axis = Axis(type = "value", scale = TRUE),
y_axis = Axis(type = "value"),
series = LineSeries(
data = mapply(c, years, year_counts, SIMPLIFY = FALSE),
smooth = TRUE
)
))year_species <- table(penguins$species, penguins$year)
groups <- rownames(year_species)
years <- as.integer(colnames(year_species))
series <- lapply(groups, function(sp) {
LineSeries(
name = sp,
data = mapply(c, years, as.integer(year_species[sp, ]), SIMPLIFY = FALSE)
)
})
draw(EChartsOption(
legend = Legend(),
x_axis = Axis(type = "value", scale = TRUE),
y_axis = Axis(type = "value"),
series = series
))AreaStyle() on a LineSeries fills the area under the line:
series <- lapply(groups, function(sp) {
LineSeries(
name = sp,
data = mapply(c, years, as.integer(year_species[sp, ]), SIMPLIFY = FALSE),
area_style = AreaStyle(opacity = 0.25)
)
})
draw(EChartsOption(
legend = Legend(),
x_axis = Axis(type = "value", scale = TRUE),
y_axis = Axis(type = "value"),
series = series
))PieSeries data is a list of named lists with value and name:
species_counts <- table(penguins$species)
data_items <- mapply(
function(v, n) list(value = v, name = n),
as.integer(species_counts),
names(species_counts),
SIMPLIFY = FALSE, USE.NAMES = FALSE
)
draw(EChartsOption(
legend = Legend(orient = "vertical", left = "left"),
series = PieSeries(data = data_items, radius = "75%")
))The S7 API gives you full access to every ECharts option. Here is an example that stacks three variables side-by-side with a shared y-axis and a custom title:
vars <- list(
`Bill Length` = penguins$bill_len,
`Flipper Length` = penguins$flipper_len
)
series <- lapply(seq_along(vars), function(i) {
d <- stats::density(na.omit(vars[[i]]))
LineSeries(
name = names(vars)[i],
data = mapply(c, d$x, d$y, SIMPLIFY = FALSE),
show_symbol = FALSE,
area_style = AreaStyle(opacity = 0.2)
)
})
draw(EChartsOption(
title = Title(text = "Penguin Measurements", subtext = "Kernel density estimate"),
legend = Legend(),
tooltip = Tooltip(trigger = "axis"),
x_axis = Axis(type = "value", scale = TRUE),
y_axis = Axis(type = "value"),
series = series
))