Open janeuhd opened 3 years ago
Hi @janeuhd nice to hear from you. If you are comfortable in R
I would say that using a traditional data.frame/tibble
with a column for color and then transforming with d3_nest
would be the easiest. Here is a quick example, but I am not sure it is clear enough for your application. This example demonstrates with sund2b
.
Let me know if you have a small shareable sample of your data, and I will be happy to help you assign and use color.
Thank you for your time!! I've tried to create a reproducible example containing the data frame behind the chart above. Hope it works for you. There are 4 level in the hierarchy (pathLA[,1:4]) which I have also combined (pathLA[,5]). Each element on each level has it own color code (pathLA[,7:9]) which I'm struggling to apply.
#Data frame
pathLA<-structure(list(ecosystem = c("Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra", "Low Arctic tundra", "Low Arctic tundra",
"Low Arctic tundra"), characteristics = c("Primary productivity",
"Primary productivity", "Primary productivity", "Primary productivity",
"Biomass distribution among trophic levels", "Biomass distribution among trophic levels",
"Biomass distribution among trophic levels", "Biomass distribution among trophic levels",
"Functional groups within trophic levels", "Functional groups within trophic levels",
"Functional groups within trophic levels", "Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Functionally important species and biophysical structures",
"Landscape ecological patterns", "Landscape ecological patterns",
"Landscape ecological patterns", "Landscape ecological patterns",
"Biological diversity", "Biological diversity", "Biological diversity",
"Biological diversity", "Biological diversity", "Biological diversity",
"Biological diversity", "Biological diversity", "Biological diversity",
"Abiotic factors", "Abiotic factors", "Abiotic factors", "Abiotic factors",
"Abiotic factors", "Abiotic factors", "Abiotic factors", "Abiotic factors",
"Abiotic factors", "Abiotic factors", "Abiotic factors", "Abiotic factors",
"Abiotic factors"), indicator = c("Maximum vegetation productivity",
"Start of growing season", "Plant biomass", "Plant phenology",
"Plant growth forms versus rodents", "Plant growth forms versus ungulates",
"Rodents versus carnivorous vertebrates", "Ungulates versus carnivorous vertebrates",
"Plant growth forms", "Herbivorous vertebrates", "Carnivorous vertebrates",
"Thicketforming willows", "Crowberry biomass", "Mountain birch in foresttundra",
"Mountain birch in foresttundra", "Lemming abundance", "Ptarmigan density",
"Geometrid moth outbreaks", "Geometrid moth outbreaks", "Semidomestic reindeer abundance",
"Semidomestic reindeer calf body mass", "Semidomestic reindeer calf rate",
"Red fox camera index", "Large predators", "Insect communities in dead wood",
"Large raptors", "Mountain birch in tundra", "Pollinators", "Snowbed encroachment",
"Bioclimatic subzones", "Wilderness areas", "Forest/shrub line",
"Plant communities", "Arctic fox abundance", "Arctic fox litter size",
"Arctic fox camera index", "Snowy owl abundance", "Snowy owl fecundity",
"Bird communities intensive", "Bird communities extensive", "Arthropod diversity",
"Days with extreme cold", "Winter melt days", "Degree days",
"Growing degree days", "Annual mean temperature", "January mean temperature",
"July mean temperature", "Annual precipitation", "Precipitation during growing season",
"Snow cover duration", "Basal ice", "Albedo", "Snow quality and structure"
), phenomenon = c("LP01", "LP02", "LP03", "LPx1", "LP04", "LP05",
"LP06", "LP07", "LP08", "LP09", "LP10", "LP11", "LP12", "LP13",
"LP14", "LP15", "LP16", "LP17", "LP18", "LP19", "LP20", "LP21",
"LP22", "LP23", "LPx2", "LPx3", "LPx4", "LPx5", "LP24", "LP25",
"LP26", "LPx6", "LP27", "LP28", "LP29", "LP30", "LP31", "LP32",
"LP33", "LPx7", "LPx8", "LP34", "LP35", "LP36", "LP37", "LP38",
"LP39", "LP40", "LP41", "LP42", "LP43", "LP44", "LPx9", "LPx10"
), leafs = c("Low Arctic tundra-Primary productivity-Maximum vegetation productivity-LP01",
"Low Arctic tundra-Primary productivity-Start of growing season-LP02",
"Low Arctic tundra-Primary productivity-Plant biomass-LP03",
"Low Arctic tundra-Primary productivity-Plant phenology-LPx1",
"Low Arctic tundra-Biomass distribution among trophic levels-Plant growth forms versus rodents-LP04",
"Low Arctic tundra-Biomass distribution among trophic levels-Plant growth forms versus ungulates-LP05",
"Low Arctic tundra-Biomass distribution among trophic levels-Rodents versus carnivorous vertebrates-LP06",
"Low Arctic tundra-Biomass distribution among trophic levels-Ungulates versus carnivorous vertebrates-LP07",
"Low Arctic tundra-Functional groups within trophic levels-Plant growth forms-LP08",
"Low Arctic tundra-Functional groups within trophic levels-Herbivorous vertebrates-LP09",
"Low Arctic tundra-Functional groups within trophic levels-Carnivorous vertebrates-LP10",
"Low Arctic tundra-Functionally important species and biophysical structures-Thicketforming willows-LP11",
"Low Arctic tundra-Functionally important species and biophysical structures-Crowberry biomass-LP12",
"Low Arctic tundra-Functionally important species and biophysical structures-Mountain birch in foresttundra-LP13",
"Low Arctic tundra-Functionally important species and biophysical structures-Mountain birch in foresttundra-LP14",
"Low Arctic tundra-Functionally important species and biophysical structures-Lemming abundance-LP15",
"Low Arctic tundra-Functionally important species and biophysical structures-Ptarmigan density-LP16",
"Low Arctic tundra-Functionally important species and biophysical structures-Geometrid moth outbreaks-LP17",
"Low Arctic tundra-Functionally important species and biophysical structures-Geometrid moth outbreaks-LP18",
"Low Arctic tundra-Functionally important species and biophysical structures-Semidomestic reindeer abundance-LP19",
"Low Arctic tundra-Functionally important species and biophysical structures-Semidomestic reindeer calf body mass-LP20",
"Low Arctic tundra-Functionally important species and biophysical structures-Semidomestic reindeer calf rate-LP21",
"Low Arctic tundra-Functionally important species and biophysical structures-Red fox camera index-LP22",
"Low Arctic tundra-Functionally important species and biophysical structures-Large predators-LP23",
"Low Arctic tundra-Functionally important species and biophysical structures-Insect communities in dead wood-LPx2",
"Low Arctic tundra-Functionally important species and biophysical structures-Large raptors-LPx3",
"Low Arctic tundra-Functionally important species and biophysical structures-Mountain birch in tundra-LPx4",
"Low Arctic tundra-Functionally important species and biophysical structures-Pollinators-LPx5",
"Low Arctic tundra-Landscape ecological patterns-Snowbed encroachment-LP24",
"Low Arctic tundra-Landscape ecological patterns-Bioclimatic subzones-LP25",
"Low Arctic tundra-Landscape ecological patterns-Wilderness areas-LP26",
"Low Arctic tundra-Landscape ecological patterns-Forest/shrub line-LPx6",
"Low Arctic tundra-Biological diversity-Plant communities-LP27",
"Low Arctic tundra-Biological diversity-Arctic fox abundance-LP28",
"Low Arctic tundra-Biological diversity-Arctic fox litter size-LP29",
"Low Arctic tundra-Biological diversity-Arctic fox camera index-LP30",
"Low Arctic tundra-Biological diversity-Snowy owl abundance-LP31",
"Low Arctic tundra-Biological diversity-Snowy owl fecundity-LP32",
"Low Arctic tundra-Biological diversity-Bird communities intensive-LP33",
"Low Arctic tundra-Biological diversity-Bird communities extensive-LPx7",
"Low Arctic tundra-Biological diversity-Arthropod diversity-LPx8",
"Low Arctic tundra-Abiotic factors-Days with extreme cold-LP34",
"Low Arctic tundra-Abiotic factors-Winter melt days-LP35", "Low Arctic tundra-Abiotic factors-Degree days-LP36",
"Low Arctic tundra-Abiotic factors-Growing degree days-LP37",
"Low Arctic tundra-Abiotic factors-Annual mean temperature-LP38",
"Low Arctic tundra-Abiotic factors-January mean temperature-LP39",
"Low Arctic tundra-Abiotic factors-July mean temperature-LP40",
"Low Arctic tundra-Abiotic factors-Annual precipitation-LP41",
"Low Arctic tundra-Abiotic factors-Precipitation during growing season-LP42",
"Low Arctic tundra-Abiotic factors-Snow cover duration-LP43",
"Low Arctic tundra-Abiotic factors-Basal ice-LP44", "Low Arctic tundra-Abiotic factors-Albedo-LPx9",
"Low Arctic tundra-Abiotic factors-Snow quality and structure-LPx10"
), size = c(1.75, 1.75, 1.75, 1.75, 1.75, 1.75, 1.75, 1.75, 2.33333333333333,
2.33333333333333, 2.33333333333333, 0.411764705882353, 0.411764705882353,
0.411764705882353, 0.411764705882353, 0.411764705882353, 0.411764705882353,
0.411764705882353, 0.411764705882353, 0.411764705882353, 0.411764705882353,
0.411764705882353, 0.411764705882353, 0.411764705882353, 0.411764705882353,
0.411764705882353, 0.411764705882353, 0.411764705882353, 1.75,
1.75, 1.75, 1.75, 0.777777777777778, 0.777777777777778, 0.777777777777778,
0.777777777777778, 0.777777777777778, 0.777777777777778, 0.777777777777778,
0.777777777777778, 0.777777777777778, 0.538461538461539, 0.538461538461539,
0.538461538461539, 0.538461538461539, 0.538461538461539, 0.538461538461539,
0.538461538461539, 0.538461538461539, 0.538461538461539, 0.538461538461539,
0.538461538461539, 0.538461538461539, 0.538461538461539), hex_char = c("#ffc000",
"#ffc000", "#ffc000", "#ffc000", "#ffc000", "#ffc000", "#ffc000",
"#ffc000", "#ffc000", "#ffc000", "#ffc000", "#ffc000", "#ffc000",
"#ffc000", "#ffc000", "#ffc000", "#ffc000", "#ffc000", "#ffc000",
"#ffc000", "#ffc000", "#ffc000", "#ffc000", "#ffc000", "#ffc000",
"#ffc000", "#ffc000", "#ffc000", "#ff6600", "#ff6600", "#ff6600",
"#ff6600", "#ff6600", "#ff6600", "#ff6600", "#ff6600", "#ff6600",
"#ff6600", "#ff6600", "#ff6600", "#ff6600", "#ff6600", "#ff6600",
"#ff6600", "#ff6600", "#ff6600", "#ff6600", "#ff6600", "#ff6600",
"#ff6600", "#ff6600", "#ff6600", "#ff6600", "#ff6600"), hex_ind = c("#d9d9d9",
"#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9",
"#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9",
"#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9",
"#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9",
"#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9",
"#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9",
"#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9",
"#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9",
"#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9", "#d9d9d9"), hex_phen = c("#ffc000",
"#ffc000", "#ffc000", "#d9d9d9", "#92d050", "#ffc000", "#92d050",
"#ffc000", "#ffc000", "#92d050", "#ffc000", "#92d050", "#ffc000",
"#92d050", "#ff6600", "#ffc000", "#ffc000", "#ff6600", "#ff6600",
"#ffc000", "#92d050", "#92d050", "#ffc000", "#ff6600", "#d9d9d9",
"#d9d9d9", "#d9d9d9", "#d9d9d9", "#ffc000", "#ff6600", "#ffc000",
"#d9d9d9", "#ffc000", "#ff6600", "#ff6600", "#ff6600", "#ff6600",
"#92d050", "#ff6600", "#d9d9d9", "#d9d9d9", "#ff6600", "#ff6600",
"#ff6600", "#ff6600", "#ff6600", "#ff6600", "#ff6600", "#ffc000",
"#92d050", "#ff6600", "#92d050", "#d9d9d9", "#d9d9d9")), class = "data.frame", row.names = c(NA,
-54L))
str(pathLA)
#Path and values will give a sunburst chart with the correct sizes to each leaf. This is the desired shape of the final chart
sunburst(pathLA[,5:6])
#Using the levels directly in treemap will gve a treemap with the correct sizes, and I can apply the desired colors to each polygon,
#but only for 1 level at a time (e.g. either col_char, col_ind, or col_phen)
tm.LA<-treemap(pathLA, index=c("characteristics","indicator", "phenomenon"),vSize="size",vColor="hex_phen",type="color")
tm_nest.LA<-d3_nest(
tm.LA$tm[,c("characteristics","indicator", "phenomenon","vSize","color")],
value_cols=c("vSize","color"))
#My problem is: how do I apply the desired colors (which are now in 3 coloumns in pathLA each representing a level) to each level in the sunburst diagram?
sunburst(data = tm_nest.LA,
valueField = "vSize",
count = TRUE,
# to avoid double counting with pre-summed trees
# use sumNodes = FALSE
sumNodes = TRUE,
colors = htmlwidgets::JS("function(d){return d3.select(this).datum().data.color;}"),
withD3 = TRUE)
# sessionInfo()
# R version 4.0.3 (2020-10-10)
# Platform: x86_64-w64-mingw32/x64 (64-bit)
# Running under: Windows 10 x64 (build 19043)
#
# Matrix products: default
#
# locale:
# [1] LC_COLLATE=English_Europe.1252 LC_CTYPE=English_Europe.1252 LC_MONETARY=English_Europe.1252 LC_NUMERIC=C LC_TIME=English_Europe.1252
#
# attached base packages:
# [1] stats graphics grDevices utils datasets methods base
#
# other attached packages:
# [1] dplyr_1.0.3 plotly_4.10.0 ggplot2_3.3.3 treemap_2.4-3 d3r_1.0.0 sunburstR_2.1.6
#
# loaded via a namespace (and not attached):
# [1] Rcpp_1.0.7 pillar_1.4.7 compiler_4.0.3 RColorBrewer_1.1-2 later_1.1.0.1 tools_4.0.3 digest_0.6.27 viridisLite_0.3.0 jsonlite_1.7.2
# [10] gtable_0.3.0 evaluate_0.14 lifecycle_0.2.0 tibble_3.0.6 gridBase_0.4-7 pkgconfig_2.0.3 rlang_0.4.10 igraph_1.2.7 rstudioapi_0.13
# [19] shiny_1.6.0 DBI_1.1.1 crosstalk_1.1.1 yaml_2.2.1 xfun_0.20 fastmap_1.1.0 httr_1.4.2 withr_2.4.1 knitr_1.31
# [28] generics_0.1.0 vctrs_0.3.6 htmlwidgets_1.5.3 grid_4.0.3 tidyselect_1.1.0 glue_1.4.2 data.table_1.13.6 R6_2.5.0 rmarkdown_2.6
# [37] tidyr_1.1.2 purrr_0.3.4 magrittr_2.0.1 scales_1.1.1 promises_1.1.1 ellipsis_0.3.1 htmltools_0.5.1.1 assertthat_0.2.1 mime_0.9
# [46] colorspace_2.0-0 xtable_1.8-4 httpuv_1.5.5 lazyeval_0.2.2 munsell_0.5.0 crayon_1.4.0
does this do what you want sunburst(pathLA[, 5:6], colors = pathLA$hex_phen)
?
No, unfortunately it does not. 'hex_phen' contains the colors which should go on the outer ring only (the ring containing 'phenomenon'). Similarly, 'hex_ind' contains the colors which should go the the ring containing 'indicators', while 'hex_char' contains the colors which should go on the ring containing 'characteristics'.
@janeuhd I do not think this is exactly what you want, but I hope it gets closer. We can discard the leafs
column and the old data format, and I think just use the data.frame
. Then, we can apply some logic in JavaScript to pick the color. It appears that indicator
and phenomenon
are one-to-one. If so, then we could combine the two or eliminate one of those columns. We could also add color to the root.
As another option we could change the data structure to add color to non-leaf nodes to remove the JavaScript logic.
sunburst(
d3_nest(
pathLA[,-5],
value_cols = c(colnames(pathLA)[6:9])
),
colors = htmlwidgets::JS("
function(d) {
var node = d3.select(this).datum();
var dat = node.data;
if(node.depth > 0 && dat.colname === 'characteristics') {
return node.leaves()[0].data.hex_char;
}
if(node.depth > 0 && dat.colname === 'indicator') {
return node.leaves()[0].data.hex_ind;
}
return dat.hex_phen
}
"),
withD3 = TRUE
)
Thanks a bundle! This comes very close. The indicator and phenomenon level are not exactly identical as there are sometimes cases of multiple phenomena per indicator (in this example only 2 cases though). But both levels are needed.
I wonder though whether it is possible also to tweak the inner radius in each node level to allow each level to be of a different width? I'm thinking that I could remove the 1st level (ecosystem) and pull the 2nd level in towards the centre to allow the grey level (indicators) to be wider than the rest, since this a level which require fairly long labels. There is no need for a large white space in the middle.
sunburst(
d3_nest(
pathLA[,c(-1,-5)], #skip the inner level
value_cols = c(colnames(pathLA)[6:9]),
),
percent=FALSE,
colors = htmlwidgets::JS("
function(d) {
var node = d3.select(this).datum();
var dat = node.data;
if(node.depth > 0 && dat.colname === 'characteristics') {
return node.leaves()[0].data.hex_char;
}
if(node.depth > 0 && dat.colname === 'indicator') {
return node.leaves()[0].data.hex_ind;
}
return dat.hex_phen
}
"),
#adjustment of inner radius/level width possible?
withD3 = TRUE
)
@janeuhd As of now there is no support for tweaking inner radius. To further the discussion, I wanted to demonstrate how we could use the flattree
data structure to add color at the parent level. Here is a very ugly example (sorry to add a dependency with dplyr
). I also introduce sund2b
since we then get zoom interaction and showLabels
.
pathLA2 <- dplyr::bind_rows(
dplyr::rename(
pathLA,
color = hex_phen
),
# add parents denoted by NA in all columns that are children
# so I inelegantly/lazily go through each level of the hierarchy - ecosystem, characteristics, indicator, phenomenon
# and add or get color
dplyr::rename(
unique(pathLA[,c("ecosystem","characteristics","hex_char")]),
color = hex_char
),
dplyr::rename(
unique(pathLA[,c("ecosystem","characteristics","indicator","hex_ind")]),
color = hex_ind
),
dplyr::rename(
unique(pathLA[,c("ecosystem","characteristics","indicator","phenomenon","hex_phen")]),
color = hex_phen
)
)
sund2b(
d3_nest(
pathLA2[,-c(1,5,7,8)], # remove leafs, hex_ind, and hex_phen
value_cols = c("size","color"),
root = "Low Arctic tundra"
),
colors = htmlwidgets::JS(
# yes this is a little different, so please pay attention
# "function(d) {return d.color}" will not work
"function(name, d){debugger; return d.color || '#ccc';}"
),
showLabels = TRUE
)
Hi, Thanks for a great package which I hope to use for producing overviews of the assessment of ecological indicators. Assessments are hierarchical over 3-4 levels and each leaf have an associated assessment category (e.g. color). This means that I need to be able to custom color each leaf, and I cannot figure out how to do that. There are many leaves (see example figure below, random colors) so manual tweaking is not an option. Can you point me to a solution?
Thanks, Jane