Function for plotting the original network with nodes colored according to the community partition identified via the clique percolation community detection algorithm, taking predefined sets of nodes into account.
1 2 3 4 5 6 7 8 9 10 11 12 13
A qgraph object or a symmetric matrix; see also qgraph
List object taken from results of cpAlgorithm function; see also cpAlgorithm
List object specifying predefined groups of nodes in original network; default is NULL; see Details
Integer indicating whether
Vector of integers indicating the range of hue from which
colors should be drawn for elements in
Integer indicating the chroma from which
colors should be drawn for elements in
Integer indicating the luminance from which
colors should be drawn for elements in
Integer indicating the number of sets for which smooth gradients of a set color should be generated using colorspace::sequential_hcl(); default is the number of pure communities of a set plus one; see Details
Vector of hex code colors of length of
Logical indicating whether it should be avoided that multiple mixed communities are assigned the same color; default is FALSE; see Details
any additional argument from qgraph; see also qgraph
The function takes the results of cpAlgorithm (see also cpAlgorithm),
that is, either the
list.of.communities.numbers or the
list.of.communities.labels and plots the original network, coloring
the nodes according to the community partition. If there are no predefined
sets of nodes (
list.of.sets = NULL; the default), each community is
assigned a color by using a palette generation algorithm from the package
colorspace, which relies on HCL color space. Specifically, the function
qualitative_hcl (see also
colorspace::qualitative_hcl() is used,
which generates a balanced set of colors over a range of hue values, holding
chroma and luminance constant. This method is preferred over other palette
generating algorithms in other color spaces (Zeileis et al., subm.). The
default values recommended in qualitative_hcl are used, adapted to the
current context in the case of hue. Yet, h.cp, c.cp, and l.cp can be used
to overwrite the default values. Each node gets the color of the community
it belongs to. Shared nodes are split equally in multiple colors, one for
each community they belong to. Isolated nodes are colored white.
If there are predefined sets of nodes, the qualitatively different colors
are assigned to the sets specified in
list.of.sets. Then, it is
checked whether communities are pure (they contain nodes from only one set)
or they are mixed (they contain nodes from multiple sets). For pure
communities of each set, the assigned color is taken and faded towards white
with another function from colorspace, namely sequential_hcl
(see also colorspace::sequential_hcl(). For
instance, if there are three pure communities with nodes that are only from
Set 1, then the basic color assigned to Set 1 is taken, and faded toward white
in 3 + 1 steps. There is one color generated more than needed (here four colors
for three communities), because the last color in the fading is always white, which
is reserved for isolated nodes. The three non-white colors are then assigned
to each community, with stronger colors being assigned to larger communities.
In that sense, all communities that entail nodes from only one specific set, will
have rather similar colors (only faded towards white). All communities that
entail nodes from only one specific other set, will also have similar colors,
yet they will differ qualitatively from the colors of the communities that
entail items from other sets. For communities that entail items from multiple
sets, the basic colors assigned to these sets are mixed in proportion to the
number of nodes from each set. For instance, if a community entails two nodes
from Set 1 and one node from Set 2, then the colors of Sets 1 and 2 are mixed
The mixing of colors is subtractive (how paint mixes). Subtractive color mixing is difficult to implement. An algorithm proposed by Scott Burns is used (see http://scottburns.us/subtractive-color-mixture/ and http://scottburns.us/fast-rgb-to-spectrum-conversion-for-reflectances/). Each color is transformed into a corresponding reflectance curve via the RGBC algorithm. That is, optimized reflectance curves of red, green, and blue are adapted according to the RGB values of the respective color. The reflectance curves of the colors that need to be mixed are averaged via the weighted geometric mean. The resulting mixed reflectance curve is transformed back to RGB values by multiplying the curve with a derived matrix. The algorithm produces rather good color mixing and is computationally efficient. Yet, results may not always be absolutely precise.
The mixing of colors for mixed communities can lead to multiple communities
being assigned the same color. For instance, two communities with two nodes
each from Sets 1 and 2 would have the same color, namely the colors assigned to
the sets mixed in the same proportion. This is reasonable, because these
communities are structurally similar. However, it can be confusing to have
two actually different communities with the same color. To avoid this,
avoid.repeated.mixed.colors = TRUE. Doing so slightly alters the
ratio with which the color of a mixed community is determined, if the
community would have been assigned a color that was already assigned.
This slight variation of the ratio is random. To reproduce results from a
previous run, set a seed.
The fading of pure communities via sequential_hcl is a function of
the number of sets. If there are more pure communities from a specific
set, more faded colors will be generated. This makes coloring results hard
to compare across different networks, if such a comparison is desired.
For instance, if one network has 12 nodes that belong to three communities
sized 6, 3, and 3, all of them pure (having nodes from only one set), then
their colors will be strong, average, and almost white respectively. If the
same 12 nodes belong to two communities size 6 and 6, both of them pure, then
their colors will be strong and average to almost white. Different numbers
of pure communities therefore change the color range. To circumvent that,
one can specify
set.palettes.size to any number larger than the number
of pure communities of a set plus one. For all sets, sequential_hcl
then generates as many shades towards white of a respective color as specified
set.palettes.size. Colors for each community are then picked
from the strongest towards whiter colors, with larger communities being
assigned stronger colors. Note that in this situation, the range of colors
is always the same for all sets in a network, making them comparable across
different sets. When there are more pure communities of one set than from another
their luminance will be lower. Moreover, also across networks, the luminance
of different sets of nodes or of the same set can be compared.
In all cases, qualitatively different colors are assigned to either the elements
list.of.sets = NULL) or the elements
list.of.sets is not NULL) with qualitative_hcl.
Zeileis et al. (subm.) argue that this function can generate up to six
different colors that people can still distinguish. For a larger number of
qualitative colors, other packages can be used. Specifically, if the argument
larger.six = TRUE (default is
FALSE), the qualitatively
different colors are generated via the package Polychrome (Coombes et al., 2019)
with the function createPalette (see also createPalette).
This function generates maximally different colors in HCL space and can generate a
higher number of distinct colors. With these colors, the rest of the procedure is
identical. The seedcolors specified in Polychrome are general red, green, and
blue. As the procedure relies on randomness, you have to set a seed to reproduce
the results of a previous run.
Note that the Polychrome palettes are maximally distinct, thus they are
most likely not as balanced as the palettes generated with colorspace. In general,
the function cpColoredGraph is recommended only for very small networks
anyways, for which
larger.six = FALSE makes sense. For larger networks,
consider plotting the community network instead (see cpCommunityGraph).
When own.colors are specified, these colors are assigned to the elements in
list.of.sets = NULL) or to the elements
list.of.sets is not NULL). The rest of the
procedure is identical.
The function primarily plots the original network and colors the nodes according to the communities, taking predefined sets into account. Additionally, it returns a list with the following elements:
Vector with colors assigned to the elements in
list.of.sets is not NULL. Otherwise NULL is returned.
Vector with colors of the communities, namely assigned
list.of.sets = NULL or shaded and mixed colors if
list.of.sets is not NULL.
List with all colors assigned to each node. Isolated nodes are white. Shared nodes have a vector of colors from each community they belong to.
Jens Lange, email@example.com
Coombes, K. R., Brock, G., Abrams, Z. B., & Abruzzo, L. V. (2019). Polychrome: Creating and assessing qualitative palettes with many colors. Journal of Statistical Software, 90, 1-26. https://doi.org/10.18637/jss.v090.c01
Zeileis, A., Fisher, J. C., Hornik, K., Ihaka, R., McWhite, C. D., Murrell, P., Stauffer, R., & Wilke, C. O. (subm.). colorspace: A toolbox for manipulating and assessing colors and palettes. https://arxiv.org/abs/1903.06490
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
## Example with fictitious data # generate qgraph object with letters as labels W <- matrix(c(0,0.10,0,0,0,0.10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0.10,0,0,0.10,0.20,0,0,0,0,0.20,0.20,0,0,0,0,0,0,0,0, 0,0,0,0.10,0,0.10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0.10,0.10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0.10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0.20,0,0,0,0,0.20,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0.20,0,0,0,0.20,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0.20,0,0,0.20,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0.20,0,0.20,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0.20,0.20,0.30,0,0,0,0,0.30,0.30,0, 0,0,0,0,0,0,0,0,0,0,0,0,0.20,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.30,0,0,0,0,0.30,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.30,0,0,0,0.30,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.30,0,0,0.30,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.30,0,0.30,0.30, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.30,0.30,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0.30,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0), nrow = 21, ncol = 21, byrow = TRUE) W <- Matrix::forceSymmetric(W) rownames(W) <- letters[seq(from = 1, to = nrow(W))] colnames(W) <- letters[seq(from = 1, to = ncol(W))] W <- qgraph::qgraph(W, layout = "spring", edge.labels = TRUE) # run clique percolation algorithm; three communities; two shared nodes, one isolated node cp <- cpAlgorithm(W, k = 3, method = "weighted", I = 0.09) # color original graph according to community partition # all other arguments are defaults; qgraph arguments used to return same layout results <- cpColoredGraph(W, list.of.communities = cp$list.of.communities.labels, layout = "spring", edge.labels = TRUE) # own colors (red, green, and blue) assigned to the communities results <- cpColoredGraph(W, list.of.communities = cp$list.of.communities.labels, own.colors = c("#FF0000","#00FF00","#0000FF"), layout = "spring", edge.labels = TRUE) # define sets of nodes; nodes a to o are in Set 1 and letters p to u in Set 2 list.of.sets <- list(letters[seq(from = 1, to = 15)], letters[seq(from = 16, to = 21)]) # color original graph according to community partition, taking sets of nodes into account # two communities are pure and therefore get shades of set color; smaller community is more white # one community is mixed, so both set colors get mixed results <- cpColoredGraph(W, list.of.communities = cp$list.of.communities.labels, list.of.sets = list.of.sets, layout = "spring", edge.labels = TRUE) # graph as before, but specifying the set palette size to 6 # from a range of 6 colors, the pure communities get the darker ones # in a different network with also two pure communities, luminance would therefore be equal results <- cpColoredGraph(W, list.of.communities = cp$list.of.communities.labels, list.of.sets = list.of.sets, set.palettes.size = 6, layout = "spring", edge.labels = TRUE) # graph as before, but colors sampled only form yellow to blue range, less chroma, more luminance results <- cpColoredGraph(W, list.of.communities = cp$list.of.communities.labels, list.of.sets = list.of.sets, set.palettes.size = 6, h.cp = c(50, 210), c.cp = 70, l.cp = 70, layout = "spring", edge.labels = TRUE) # own colors (red and green) assigned to the sets # two communities in shades of red and one community is mix of green and red (brown) results <- cpColoredGraph(W, list.of.communities = cp$list.of.communities.labels, list.of.sets = list.of.sets, own.colors = c("#FF0000","#00FF00"), layout = "spring", edge.labels = TRUE) ## Example with Obama data set (see ?Obama) # get data data(Obama) # estimate network net <- qgraph::EBICglasso(qgraph::cor_auto(Obama), n = nrow(Obama)) # run clique percolation algorithm with specific k and I cpk3I.16 <- cpAlgorithm(net, k = 3, I = 0.16, method = "weighted") # color original graph according to community partition # all other arguments are defaults results <- cpColoredGraph(net, list.of.communities = cpk3I.16$list.of.communities.labels, layout = "spring", theme = "colorblind")
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.