Paula
Paula

Reputation: 693

Plot data.tree coloring and labelling by level

I have the following data.tree structure.

d <- structure(list(SUBZONE = c("A1", "A2", "A3", "A4", "A8", "B10",  "B11", "B2", "B3", "B4"), 
                    ZONE = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "B"), 
                    ID = c(1L, 2L, 3L, 4L, 5L, 7L, 8L, 9L, 10L, 11L)), 
               .Names = c("SUBZONE", "ZONE", "ID"), 
               row.names = c(NA, 10L), 
               class = "data.frame")

d$pathString <- paste("all", d$ZONE,d$SUBZONE, sep = "/")
alltree <-as.Node(d)
plot(alltree)

This tree has three different levels, according to the graph and alltree$Get(function(x) c(level = x$level)):

enter image description here

I want to achieve two things when formatting this plot:

  1. Color by level the boxes,
  2. Label by label.

enter image description here

I don't know how to access the levels even though I tried. In this case I have "named" nodes but it's not the case for all the trees I have so I want to acces them by its level number.

Upvotes: 0

Views: 683

Answers (2)

Hank
Hank

Reputation: 1

According to https://cran.r-project.org/web/packages/data.tree/vignettes/applications.html, especially the application of Jenny Lind (decision tree, plotting), I make use of if control to filter the level to be modified. It looks naturally to do with this question.

d <- structure(
  list(
    SUBZONE = c("A1", "A2", "A3", "A4", "A8", "B10", "B11", "B2", "B3", "B4"),
    ZONE = c("A", "A", "A", "A", "A", "B", "B", "B", "B", "B"),
    ID = c(1L, 2L, 3L, 4L, 5L, 7L, 8L, 9L, 10L, 11L)
  ),
  .Names = c("SUBZONE", "ZONE", "ID"),
  row.names = c(NA, 10L),
  class = "data.frame"
)

d$pathString <- paste("all", d$ZONE,d$SUBZONE, sep = "/")
alltree <-as.Node(d)
plot(alltree)
#
alltree$Get(function(x) c(level = x$level))
################################### My code is below 
SetNodeStyle(
  alltree,
  style = "filled",
  fillcolor = function(node) {
    if (node$level == 1)
      "#fff200"
    else if (node$level == 2)
      c("#feadc9")
    else if (node$level == 3) {
      c("#b5e51a")
    }
  },
  fontcolor = "black",
  inherit = FALSE,
  label = function(node) {
    if (node$level == 2) {
      sapply(node$name, function(x) {
        paste0(x, "+++foo")
      })
    }
  }
)
plot(alltree) 
ToDiagrammeRGraph(alltree) |> DiagrammeR::export_graph(file_name="alltree_foo.png", file_type = "png")

alltree_plot

Upvotes: 0

Allan Cameron
Allan Cameron

Reputation: 173803

You can get a collection of all the nodes in a level by using Traverse:

level1 <- Traverse(alltree, filterFun = function(x) x$level == 1)
level2 <- Traverse(alltree, filterFun = function(x) x$level == 2)
level3 <- Traverse(alltree, filterFun = function(x) x$level == 3)

This allows you to color the nodes as required like this:

Do(level1, SetNodeStyle, style = "filled", fillcolor = "#fff200", 
   fontcolor = "black", inherit = FALSE)
Do(level2, SetNodeStyle, style = "filled", fillcolor = "#feadc9", 
   fontcolor = "black", inherit = FALSE)
Do(level3, SetNodeStyle, style = "filled", fillcolor = "#b5e51a", 
   fontcolor = "black", inherit = FALSE)

Which gives this result:

plot(alltree)

enter image description here

In terms of plotting the levels, I cannot find any native way to do this within the package itself, though presumably if you export to DiagrammeR format this would be possible.

Upvotes: 1

Related Questions