Customizing colors¶
Using link_color_func
¶
Coloring based on linkage ID¶
Colors are controlled via link_color_func
parameter of idd.create_dendrogram
function. To customize colors, pass a callable that returns an appropriate color for a given linkage ID as link_color_func
(this function also receives clustering data container which is not required in this example).
For example, to give each link/node a different color, one could do this:
#instantiate idendrogram object and pass clustering data
idd = idendrogram.idendrogram()
idd.set_cluster_info(cl_data)
#mapping from linkage_id to hex format color string
# using an arbitrary id -> rbg mapping
node_painter = lambda _, linkage_id: '#{:02x}{:02x}{:02x}'.format(
linkage_id % 255,
(linkage_id * linkage_id) % 255,
linkage_id % 3 * linkage_id % 10
)
#create a dendrogram object
dendrogram = idd.create_dendrogram(link_color_func=node_painter)
to_altair(dendrogram=dendrogram, height=200, width=629)
Coloring based on cluster ID¶
Often, dendrograms are colored so that all nodes/links that belong to a cluster are painted the same color. This requires knowledge of how to map linkage_id
to clustering information. A convenience function idendrogram.callbacks.link_painter
is available that does the mapping under the hood - all you need to provide is a list of cluster IDs and corresponding colors, and a color to be used for merged clusters.
cluster_painter = idendrogram.callbacks.link_painter(
colors={
1: 'red',
2: 'blue',
3: 'green',
},
above_threshold='black'
)
#create a dendrogram object
dendrogram = idd.create_dendrogram(link_color_func=cluster_painter)
to_altair(dendrogram=dendrogram, height=200, width=629)
Changing default text colors¶
Default colors of nodes and links are defined in idendrogram.containers.ClusterNode
and idendrogram.containers.ClusterLink
. You can either set different defaults in advance or post-process after the dendrogram is created.
Setting different defaults¶
The easiest way to change defaults is by defining a new dataclass with appropriate values and passing it to the idendrogram()
constructor.
from idendrogram.containers import ClusterNode
from dataclasses import dataclass
@dataclass
class MyNode(ClusterNode):
labelcolor: str = 'pink'
edgecolor: str = 'orange'
fillcolor: str = 'yellow'
idd = idendrogram.idendrogram(node_factory=lambda x: MyNode(**x))
idd.set_cluster_info(cl_data)
# make nodes black-ish otherwise
node_painter = lambda _, linkage_id: '#{:02x}{:02x}{:02x}'.format(
0,
0,
(linkage_id) % 255,
)
#create a dendrogram object
dendrogram = idd.create_dendrogram(link_color_func=node_painter)
to_altair(dendrogram=dendrogram, height=200, width=629)
Monochrome dendrograms¶
Note that nodes are still colored using the default link_color_func
parameter, so if you want to have a completely single-colored dendrogram version, you need to change that, too.
@dataclass
class MonochromeNode(ClusterNode):
labelcolor: str = 'white'
edgecolor: str = 'grey'
fillcolor: str = 'grey'
idd = idendrogram.idendrogram(node_factory=lambda x: MonochromeNode(**x))
idd.set_cluster_info(cl_data)
# make nodes black-ish otherwise
grey_painter = lambda _, __: "grey"
#create a dendrogram object
dendrogram = idd.create_dendrogram(link_color_func=grey_painter)
to_altair(dendrogram=dendrogram, height=200, width=629)
Coloring in post-processing¶
You can also redefine color values or each node and link separately after the dendrogram has been created.
dendrogram = idd.create_dendrogram()
for i, n in enumerate(dendrogram.nodes):
if i % 2 == 0:
n.edgecolor = 'red'
n.fillcolor = 'red'
n.labelcolor = 'lightgrey'
else:
n.edgecolor = 'lightgrey'
n.fillcolor = 'lightgrey'
n.labelcolor = 'red'
for i, l in enumerate(dendrogram.links):
if i % 2 == 0:
l.fillcolor = 'blue'
else:
l.fillcolor = 'green'
to_altair(dendrogram=dendrogram, height=200, width=629)