The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
Load the ‘d3po’ package and also ‘sf’ (geomaps) and ‘igraph’ (networks):
These examples are organized by chart type. Each section is self-contained and can be run independently.
A ‘d3po’ object can be created with the following minimal syntax or variations of it depending on the chart type:
trade_by_continent <- d3po::trade[d3po::trade$year == 2023L, ]
trade_by_continent <- aggregate(
trade ~ reporter_continent,
data = d3po::trade,
FUN = sum
)
# Assign colors to continents
my_pal <- tintin::tintin_pal()(7)
names(my_pal) <- c(
"Africa", "Antarctica", "Asia",
"Europe", "North America", "Oceania", "South America"
)
d3po(trade_by_continent, width = 800, height = 600) %>%
po_bar(daes(x = reporter_continent, y = trade, color = my_pal)) %>%
po_labels(
x = "Continent",
y = "Trade (USD billion)",
title = "Total Trade by Reporter Continent in 2023"
)trade_by_continent$color <- my_pal[trade_by_continent$reporter_continent]
d3po(trade_by_continent, width = 800, height = 600) %>%
po_bar(daes(x = trade, y = reporter_continent, color = color)) %>%
po_labels(
x = "Trade (USD billion)",
y = "Continent",
title = "Total Trade by Reporter Continent in 2023"
)trade_stacked <- d3po::trade
trade_stacked <- aggregate(trade ~ reporter_continent + partner_continent, data = trade_stacked, FUN = sum)
trade_stacked$color <- ifelse(trade_stacked$partner_continent == "Africa", my_pal["Africa"], NA)
trade_stacked$color <- ifelse(trade_stacked$partner_continent == "Antarctica", my_pal["Antarctica"], trade_stacked$color)
trade_stacked$color <- ifelse(trade_stacked$partner_continent == "Asia", my_pal["Asia"], trade_stacked$color)
trade_stacked$color <- ifelse(trade_stacked$partner_continent == "Europe", my_pal["Europe"], trade_stacked$color)
trade_stacked$color <- ifelse(trade_stacked$partner_continent == "North America", my_pal["North America"], trade_stacked$color)
trade_stacked$color <- ifelse(trade_stacked$partner_continent == "Oceania", my_pal["Oceania"], trade_stacked$color)
trade_stacked$color <- ifelse(trade_stacked$partner_continent == "South America", my_pal["South America"], trade_stacked$color)
d3po(trade_stacked, width = 800, height = 600) %>%
po_bar(daes(
x = reporter_continent, y = trade, group = partner_continent,
color = color, stack = TRUE
)) %>%
po_labels(
x = "Reporter Continent",
y = "Trade (USD billion)",
title = "Trade Distribution by Reporter and Partner Continent in 2023"
)d3po(trade_by_continent, width = 800, height = 600) %>%
po_bar(daes(x = reporter_continent, y = trade, color = my_pal)) %>%
po_labels(
x = "Reporter Continent",
y = "Trade (USD billion)",
title = "Total Trade by Reporter Continent in 2023"
) %>%
po_theme(axis = "#012169", tooltip = "#101418", background = "#cccccc") %>%
po_font("Liberation Serif", 12, "uppercase") %>%
po_download(FALSE)d3po(trade_by_continent, width = 800, height = 600) %>%
po_pie(daes(size = trade, group = reporter_continent, color = my_pal)) %>%
po_labels(title = "Trade Share by Reporter Continent in 2023") %>%
po_theme(tooltip = "#101418", background = "#cccccc") %>%
po_font("Liberation Serif", 12, "uppercase") %>%
po_download(FALSE)trade_by_continent <- d3po::trade
trade_by_continent <- aggregate(
trade ~ year + reporter_continent,
data = trade_by_continent,
FUN = sum
)
# Assign colors to continents
my_pal <- tintin::tintin_pal(option = "Cigars of the Pharaoh")(7)
names(my_pal) <- c(
"Africa", "Antarctica", "Asia",
"Europe", "North America", "Oceania", "South America"
)
d3po(trade_by_continent, width = 800, height = 600) %>%
po_area(daes(
x = year, y = trade, group = reporter_continent, color = my_pal
)) %>%
po_labels(
x = "Year",
y = "Trade (USD billion)",
title = "Trade Distribution by Reporter Continent in 2019 and 2023"
)trade_by_continent$color <- my_pal[trade_by_continent$reporter_continent]
d3po(trade_by_continent, width = 800, height = 600) %>%
po_area(daes(
x = year, y = trade, group = reporter_continent, color = color
)) %>%
po_labels(
x = "Year",
y = "Trade (USD billion)",
title = "Trade Distribution by Reporter Continent in 2019 and 2023"
)trade_by_continent$proportion <- ave(
trade_by_continent$trade,
trade_by_continent$year,
FUN = function(x) x / sum(x)
)
d3po(trade_by_continent, width = 800, height = 600) %>%
po_area(daes(
x = year, y = proportion, group = reporter_continent, color = my_pal, stack = TRUE
)) %>%
po_labels(
x = "Year",
y = "Proportion of Trade",
title = "Trade Proportions by Reporter Continent in 2019 and 2023"
)d3po(trade_by_continent, width = 800, height = 600) %>%
po_area(daes(
x = year, y = trade, group = reporter_continent, color = my_pal
)) %>%
po_labels(
x = "Year",
y = "Trade (USD billion)",
title = "Trade Distribution by Reporter Continent in 2019 and 2023"
) %>%
po_theme(axis = "#012169", tooltip = "#101418", background = "#cccccc") %>%
po_font("Liberation Serif", 12, "uppercase") %>%
po_download(FALSE)trade_by_continent <- d3po::trade
trade_by_continent <- aggregate(
trade ~ year + reporter_continent,
data = trade_by_continent,
FUN = sum
)
# Assign colors to continents
my_pal <- tintin::tintin_pal(option = "The Broken Ear")(7)
names(my_pal) <- c(
"Africa", "Antarctica", "Asia",
"Europe", "North America", "Oceania", "South America"
)
d3po(trade_by_continent, width = 800, height = 600) %>%
po_line(daes(x = year, y = trade, group = reporter_continent, color = my_pal)) %>%
po_labels(
x = "Year",
y = "Trade (USD billion)",
title = "Trade Distribution by Reporter Continent in 2019 and 2023"
)trade_by_continent$color <- my_pal[trade_by_continent$reporter_continent]
d3po(trade_by_continent, width = 800, height = 600) %>%
po_line(daes(x = year, y = trade, group = reporter_continent, color = color)) %>%
po_labels(
x = "Year",
y = "Trade (USD billion)",
title = "Trade Distribution by Reporter Continent in 2019 and 2023"
)d3po(trade_by_continent, width = 800, height = 600) %>%
po_line(daes(x = year, y = trade, group = reporter_continent, color = my_pal)) %>%
po_labels(
x = "Year",
y = "Trade (USD billion)",
title = "Trade Distribution by Reporter Continent in 2019 and 2023"
) %>%
po_theme(axis = "#012169", tooltip = "#101418", background = "#cccccc") %>%
po_font("Liberation Serif", 12, "uppercase") %>%
po_download(FALSE)# Create a wide dataset with x = 2019 and y = 2023 trade values
trade_wide_2019 <- d3po::trade[d3po::trade$year == 2019L, c("reporter", "trade")]
trade_wide_2019 <- aggregate(trade ~ reporter, data = trade_wide_2019, FUN = sum)
trade_wide_2023 <- d3po::trade[d3po::trade$year == 2023L, c("reporter", "trade")]
trade_wide_2023 <- aggregate(trade ~ reporter, data = trade_wide_2023, FUN = sum)
trade_wide <- merge(
trade_wide_2019,
trade_wide_2023,
by = "reporter",
suffixes = c("_2019", "_2023")
)
my_pal <- tintin::tintin_pal(option = "red_rackhams_treasure")(7)
d3po(trade_wide, width = 800, height = 600) %>%
po_scatter(daes(x = trade_2019, y = trade_2023, group = reporter, color = my_pal)) %>%
po_labels(
x = "Trade in 2019 (USD billion)",
y = "Trade in 2023 (USD billion)",
title = "Trade Volume by Country in 2019 and 2023"
)trade_wide$color <- sample(my_pal, nrow(trade_wide), replace = TRUE)
d3po(trade_wide, width = 800, height = 600) %>%
po_scatter(daes(x = trade_2019, y = trade_2023, group = reporter, color = color)) %>%
po_labels(
x = "Trade in 2019 (USD billion)",
y = "Trade in 2023 (USD billion)",
title = "Trade Volume by Country in 2019 and 2023"
)trade_wide$size <- (trade_wide$trade_2019 + trade_wide$trade_2023) / 2
d3po(trade_wide, width = 800, height = 600) %>%
po_scatter(daes(
x = trade_2019, y = trade_2023,
group = reporter, color = color, size = size
)) %>%
po_labels(
x = "Trade in 2019 (USD billion)",
y = "Trade in 2023 (USD billion)",
title = "Trade Volume by Country in 2019 and 2023"
)d3po(trade_wide, width = 800, height = 600) %>%
po_scatter(daes(x = trade_2019, y = trade_2023, group = reporter, color = my_pal)) %>%
po_labels(
x = "Trade in 2019 (USD billion)",
y = "Trade in 2023 (USD billion)",
title = "Trade Volume by Country in 2019 and 2023"
) %>%
po_theme(axis = "#012169", tooltip = "#101418", background = "#cccccc") %>%
po_font("Liberation Serif", 12, "uppercase") %>%
po_download(FALSE)trade_continent <- d3po::trade
trade_continent <- aggregate(
trade ~ reporter_continent + reporter,
data = trade_continent,
FUN = sum
)
my_pal <- tintin::tintin_pal(option = "Destination Moon")(7)
names(my_pal) <- c(
"Africa", "Antarctica", "Asia",
"Europe", "North America", "Oceania", "South America"
)
d3po(trade_continent, width = 800, height = 600) %>%
po_box(daes(x = reporter_continent, y = trade, color = my_pal, tooltip = reporter_continent)) %>%
po_labels(
x = "Continent",
y = "Trade (USD billion)",
title = "Trade Distribution by Reporter Continent"
)trade_continent$color <- my_pal[trade_continent$reporter_continent]
d3po(trade_continent, width = 800, height = 600) %>%
po_box(daes(y = reporter_continent, x = trade, color = color, tooltip = reporter_continent)) %>%
po_labels(
y = "Continent",
x = "Trade (USD billion)",
title = "Trade Distribution by Continents with Custom Colors"
)d3po(trade_continent, width = 800, height = 600) %>%
po_box(daes(x = reporter_continent, y = trade, color = my_pal, tooltip = reporter_continent)) %>%
po_labels(
x = "Continent",
y = "Trade (USD billion)",
title = "Trade Distribution by Reporter Continent"
) %>%
po_theme(axis = "#012169", tooltip = "#101418", background = "#cccccc") %>%
po_font("Liberation Serif", 12, "uppercase") %>%
po_download(FALSE)trade_by_continent <- d3po::trade[d3po::trade$year == 2023L, ]
trade_by_continent <- aggregate(trade ~ reporter_continent, data = trade_by_continent, FUN = sum)
my_pal <- tintin::tintin_pal(option = "The Secret of the Unicorn")(7)
names(my_pal) <- c(
"Africa", "Antarctica", "Asia",
"Europe", "North America", "Oceania", "South America"
)
d3po(trade_by_continent, width = 800, height = 600) %>%
po_treemap(daes(size = trade, group = reporter_continent, color = my_pal, tiling = "squarify")) %>%
po_labels(title = "Trade Share by Continent in 2023")trade_twolevel <- d3po::trade[d3po::trade$year == 2023L, ]
trade_twolevel <- aggregate(trade ~ reporter_continent + reporter, data = trade_twolevel, FUN = sum)
trade_twolevel$color <- my_pal[trade_twolevel$reporter_continent]
d3po(trade_twolevel, width = 800, height = 600) %>%
po_treemap(daes(
size = trade, group = reporter_continent, subgroup = reporter,
color = color, tiling = "squarify"
)) %>%
po_labels(title = "Trade Share by Continent in 2023 (click to see the countries)")d3po(trade_twolevel, width = 800, height = 600) %>%
po_treemap(daes(
size = trade, group = reporter_continent, subgroup = reporter,
color = color, tiling = "squarify"
)) %>%
po_theme(background = "#cccccc") %>%
po_font("Liberation Serif", 12, "uppercase") %>%
po_download(FALSE) %>%
po_labels(
align = "center-middle",
labels = JS(
"function(percentage, row) {
var pct = (percentage).toFixed(2) + '%';
// Show reporter (country) if available, otherwise show reporter_continent
var name = (row && row.reporter) ? row.reporter : (row && row.reporter_continent ? row.reporter_continent : '');
var count = row && (row.trade != null ? row.trade : (row.value != null ? row.value : ''));
count = (count).toFixed(2) + 'B';
return '<i>' + name + '</i><br/>Trade: ' + (count || '') + '<br/>Percentage: ' + pct;\n
}"
),
title = "Trade Share by Continent in 2023 (click to see the countries)",
subtitle = JS(
"function(_v, row) {
// row.mode is 'aggregated' | 'flat' | 'drilled'
if (row && row.mode === 'drilled') return 'Displaying Countries';
return 'Displaying Continents';\
}"
)
) %>%
po_tooltip(JS(
"function(percentage, row) {
var pct = (percentage).toFixed(2) + '%';
var count = row && row.count != null ? row.count : '';
count = (count).toFixed(2) + 'B';
if (!row || !row.reporter) {
var t1 = row && (row.reporter_continent || row.reporter) ? (row.reporter_continent || row.reporter) : '';
return '<i>Continent: ' + t1 + '</i><br/>Trade: ' + count + '<br/>Percentage: ' + pct;
}
return '<i>Continent: ' + (row.reporter_continent || '') + '<br/>Country: ' + (row.reporter || '') +
'</i><br/>Trade: ' + count + '<br/>Percentage: ' + pct;
}"
))world <- d3po::national
# Fix geometries that cross the antimeridian (date line) to avoid horizontal lines
# This affects Russia, Fiji, and other countries spanning the 180° meridian
world$geometry <- sf::st_wrap_dateline(world$geometry, options = c("WRAPDATELINE=YES"))
total_trade <- d3po::trade[d3po::trade$year == 2023L, c("reporter", "reporter_continent", "trade")]
total_trade <- aggregate(trade ~ reporter, data = total_trade, FUN = sum)
colnames(total_trade) <- c("country", "trade")
world <- merge(
world,
total_trade,
by = "country",
all.x = TRUE,
all.y = FALSE
)
my_pal <- tintin::tintin_pal(option = "The Calculus Affair")(7)
names(my_pal) <- c(
"Africa", "Antarctica", "Asia",
"Europe", "North America", "Oceania", "South America"
)
d3po(world, width = 800, height = 600) %>%
po_geomap(daes(group = country, size = trade, color = my_pal, tooltip = country)) %>%
po_labels(title = "Trade Volume by Country in 2023")europe <- world[world$continent == "Europe", ]
# Filter to continental Europe + Iceland using bounding box
# This excludes overseas territories like Canary Islands, French Guiana, etc.
bbox <- sf::st_bbox(c(xmin = -27, ymin = 30, xmax = 40, ymax = 72), crs = sf::st_crs(europe))
europe <- sf::st_crop(europe, bbox)
europe$color <- my_pal[europe$continent]
my_color <- c("#e74c3c", "#3498db", "#2ecc71")
d3po(europe, width = 800, height = 600) %>%
po_geomap(daes(group = country, size = trade, color = my_color, tooltip = country)) %>%
po_labels(title = "Trade Volume by Country in 2023")d3po(europe, width = 800, height = 600) %>%
po_geomap(daes(group = country, size = trade, color = my_color, gradient = TRUE, tooltip = country)) %>%
po_labels(title = "Trade Volume by Country in 2023") %>%
po_theme(axis = "#012169", tooltip = "#101418", background = "#cccccc") %>%
po_font("Liberation Serif", 12, "uppercase") %>%
po_download(FALSE)trade_network <- d3po::trade[d3po::trade$year == 2023L, ]
trade_network <- aggregate(trade ~ reporter_iso + partner_iso + reporter_continent + partner_continent,
data = trade_network, FUN = sum
)
# subset to 5 largest connection per reporter country
trade_network <- do.call(
rbind,
lapply(
split(trade_network, trade_network$reporter_iso),
function(df) head(df[order(-df$trade), ], 5)
)
)
# Create vertex (node) attributes for coloring and sizing
# Get unique countries with their continents and trade volumes
vertices <- unique(rbind(
data.frame(
name = trade_network$reporter_iso,
continent = trade_network$reporter_continent,
stringsAsFactors = FALSE
),
data.frame(
name = trade_network$partner_iso,
continent = trade_network$partner_continent,
stringsAsFactors = FALSE
)
))
# Remove duplicates
vertices <- vertices[!duplicated(vertices$name), ]
# Calculate total trade volume per country (as reporter)
trade_volume <- aggregate(trade ~ reporter_iso, data = trade_network, FUN = sum)
colnames(trade_volume) <- c("name", "trade_volume")
# Merge trade volume with vertices
vertices <- merge(vertices, trade_volume, by = "name", all.x = TRUE)
vertices$trade_volume[is.na(vertices$trade_volume)] <- 0
# Assign colors to continents
my_pal <- tintin::tintin_pal(option = "The Blue Lotus")(7)
names(my_pal) <- c(
"Africa", "Antarctica", "Asia",
"Europe", "North America", "Oceania", "South America"
)
# Add color column based on continent
vertices$color <- my_pal[vertices$continent]
# Create igraph object with vertex attributes
g <- graph_from_data_frame(trade_network, directed = TRUE, vertices = vertices)
# Create the network visualization
d3po(g, width = 800, height = 600) %>%
po_network(daes(size = trade_volume, color = color, layout = "fr")) %>%
po_labels(title = "Trade Network by Country in 2023")# Use a different color palette
my_pal <- tintin::tintin_pal(option = "Explorers on the Moon")(7)
names(my_pal) <- c(
"Africa", "Antarctica", "Asia",
"Europe", "North America", "Oceania", "South America"
)
# Update colors with new palette
vertices$color <- my_pal[vertices$continent]
# Create network with Kamada-Kawai layout
d3po(g, width = 800, height = 600) %>%
po_network(daes(size = trade_volume, color = color, layout = "kk")) %>%
po_labels(title = "Trade Network by Country in 2023")These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.