How to specify linewidth in Seaborn's clusterm

2020-04-14 08:30发布

问题:

Normally I would increase matplotlib's global linewidths by editing the matplotlib.rcParams. This seems to work well directly with SciPy's dendrogram implementation but not with Seaborn's clustermap (which uses SciPy's dendrograms). Can anyone suggest a working method?

import matplotlib
matplotlib.rcParams['lines.linewidth'] = 10
import seaborn as sns; sns.set()

flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")
g = sns.clustermap(flights)

回答1:

for newer versions of seaborn (tested with 0.7.1, 0.9.0), the lines are in a LineCollection, rather than by themselves. So their width can be changed as follows:

import seaborn as sns
import matplotlib.pyplot as plt

# load data and make clustermap
df = sns.load_dataset('iris')
g = sns.clustermap(df[['sepal_length', 'sepal_width']])

for a in g.ax_row_dendrogram.collections:
    a.set_linewidth(10)

for a in g.ax_col_dendrogram.collections:
    a.set_linewidth(10)


回答2:

There may be an easier way to do it, but this seems to work:

import matplotlib
import seaborn as sns; sns.set()

flights = sns.load_dataset("flights")
flights = flights.pivot("month", "year", "passengers")
g = sns.clustermap(flights)
for l in g.ax_row_dendrogram.lines:
        l.set_linewidth(10)
for l in g.ax_col_dendrogram.lines:
        l.set_linewidth(10)

Edit This no longer works in Seaborn v. 0.7.1 (and probably some earlier versions as well); g.ax_col_dendrogram.lines now returns an empty list. I couldn't find a way to increase line width and I ended up temporarily modifying the Seaborn module. In file matrix.py, function class _DendrogramPlotter, the linewidth is hard-coded as 0.5; I modified it to 1.5:

line_kwargs = dict(linewidths=1.5, colors='k')

This worked but obviously isn't a very sustainable approach.



回答3:

This has now been addressed in a more robust way by the following merged pull request https://github.com/mwaskom/seaborn/pull/1935. I'm assuming it will be included in the release after v0.9.0.

You can control the LineCollection properties of the dendrogram by using the tree_kws parameter.

For example:

>>> import seaborn as sns
>>> iris = sns.load_dataset("iris")
>>> species = iris.pop("species")
>>> g = sns.clustermap(iris, tree_kws=dict(linewidths=1.5, colors=(0.2, 0.2, 0.4))

Would create a clustermap with 1.5 pt thick lines for the tree in an alternative dark purple color.