4 geom_node_label - martin-borkovec/ggparty GitHub Wiki
geom_node_label()
is a modified version of ggplot2’s
geom_label()
which allows for multi-line labels. However the basic
functionality of geom_label()
is still present. This means that if we
are content with uniform aesthetics for the whole label, we can simply
use geom_node_label()
as we would geom_label()
with the only
difference, that x
and y
are already mapped per default to the nodes
coordinates.
If we want to have to specify even less mappings, we can use
geom_node_splitvar()
and geom_node_info()
. These are wrappers of
geom_node_label()
with the respective defaults to plot the splitvar
in the inner nodes or the info
in the terminal nodes.
geom_node_label()
allows us to create multiline labels and specify
individual graphical parameters for each line. To do this, we must not
map anything to label
in the aes()
passed to mapping
, but instead
pass a 'list'
of aes()
to the argument line_list
. The order of the
'list'
is the same as the order in which the lines will be printed.
Additionally we have to pass a 'list'
to line_gpar
. This list must
be the same length
as line_list
and contain separately named
'lists'
of graphical parameters. If we don’t want to change anything
for a specific line, the respective ’list'
hast to be an empty
'list'
.
Mapping with the mapping
argument of geom_node_label()
still works
and affects all lines and the border together. The line specific
graphical arguments in line_gpar
can be used to overwrite these
mappings
.
Additionally to the usual aethetic parameters we would use for
ggplot
’s geom_label()
we can pass parse
and alignment
through
line_gpar
. Parse is equivalent to the behaviour of geom_label()
and
alignment
enables us to position the text at the left or right label
border.
All other mappings in line_list
will be ignored. It is not possible to
map other line specific aesthetics to variables. It is only possible to
map the aesthetics of the complete label to variables and overwrite
specific lines with fixed values in line_gpar
. (In essence replicating
the condition of mapping only one line to a variable, but we won’t be
able to do this for multiple lines with different mappings).
This may seem very convoluted, but keep in mind, that we only have to go through this process if we want to address the graphical parameters of specific lines.
To create a tree consisting of inner nodes labeled by their split variable and terminal nodes labeled by their coefficients we can use the code found below.
First we need to extract the coefficients with the help of the
add_vars
argument of ggparty()
. This step is necessary so that we
can later access them by the names given to them in the 'list'
supplied to add_vars
.
Since we want to plot different elements in the inner and terminal
nodes, we need to add geom_node_label()
twice. The first call is for
the inner nodes. With the aes()
passed to mapping
we map the color
of the labels to the splitvar
of the node.
For this tree we want to display the split variable in the first line,
then the p-value in scientific notation in the second line, the third
line is just a spacer therefore empty and the fourth and last line is
supposed to show the ID of the node. We specify the aesthetics we want
to override in line_gpar
. Using the third line as a spacer and setting
alignment
to “left” we can position the id
of the node at the bottom
left corner of the labels.
Correspondingly we can plot the labels for the terminal nodes.
data("TeachingRatings", package = "AER")
tr <- subset(TeachingRatings, credits == "more")
tr_tree <- lmtree(eval ~ beauty | minority + age + gender + division + native +
tenure, data = tr, weights = students, caseweights = FALSE)
ggparty(tr_tree,
terminal_space = 0,
add_vars = list(intercept = "$node$info$coefficients[1]",
beta = "$node$info$coefficients[2]")) +
geom_edge(size = 1.5) +
geom_edge_label(colour = "grey", size = 4) +
# first label inner nodes
geom_node_label(# map color of complete label to splitvar
mapping = aes(col = splitvar),
# map content to label for each line
line_list = list(aes(label = splitvar),
aes(label = paste("p =",
formatC(p.value,
format = "e",
digits = 2))),
aes(label = ""),
aes(label = id)
),
# set graphical parameters for each line in same order
line_gpar = list(list(size = 12),
list(size = 8),
list(size = 6),
list(size = 7,
col = "black",
fontface = "bold",
alignment = "left")
),
# only inner nodes
ids = "inner") +
# next label terminal nodes
geom_node_label(# map content to label for each line
line_list = list(
aes(label = paste("beta[0] == ", round(intercept, 2))),
aes(label = paste("beta[1] == ",round(beta, 2))),
aes(label = ""),
aes(label = id)
),
# set graphical parameters for each line in same order
line_gpar = list(list(size = 12, parse = T),
list(size = 12, parse = T),
list(size = 6),
list(size = 7,
col = "black",
fontface = "bold",
alignment = "left")),
ids = "terminal",
# nudge labels towards bottom so that edge labels have enough space
# alternatively use shift argument of edge_label
nudge_y = -.05) +
# don't show legend for splitvar mapping to color since self-explanatory
theme(legend.position = "none") +
# html_documents seem to cut off a bit too much at the edges so set limits manually
coord_cartesian(xlim = c(0, 1), ylim = c(-0.1, 1.1))