Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ClusterGrid layouts: fixing longstanding issues #1393

Closed
wants to merge 7 commits into from

Conversation

lukauskas
Copy link
Contributor

This PR fixes a few of annoying things with sns.clustermap that have been there for since I remember.

Here's a detailed list with some examples

Fix 1: Fix the clustermap scaling with size: dendrogram should not scale

The heatmap scaling has been completely broken since forever.
The code claims that it is set up so only the heatmap scales, not the dendrogram, but this is not the case:

import seaborn as sns; sns.set(color_codes=True)
iris = sns.load_dataset("iris")
species = iris.pop("species")
lut = dict(zip(species.unique(), "rbg"))
row_colors = species.map(lut)
g = sns.clustermap(iris, row_colors=row_colors, figsize=(5, 5))
g = sns.clustermap(iris, row_colors=row_colors, figsize=(10, 5))
g = sns.clustermap(iris, row_colors=row_colors, figsize=(5, 10))

5,5:

image

10,5:
image

5,10:
image

With this PR, 10,5:

image

With this PR 5, 10:
image

Fix 2: prevent squashing of row_colors when multiple annotations are given

row_colors_multiple = pd.DataFrame({'foo': species.map(dict(zip(species.unique(), sns.color_palette('Set1', 3).as_hex()))),
                                    'bar': species.map(dict(zip(species.unique(), sns.color_palette('Set2', 3).as_hex()))),
                                    'baz': species.map(dict(zip(species.unique(), sns.color_palette('Set3', 3).as_hex()))),
                                    'boo': species.map(dict(zip(species.unique(), sns.color_palette('Dark2', 3).as_hex())))})
g = sns.clustermap(iris, row_colors=row_colors_multiple, figsize=(5, 5))

Before:

image

After:

image

Fix 3: Extend colorbar through the whole length of dendrogram and row_colors if provided

g = sns.clustermap(iris.T, col_colors=row_colors_multiple, figsize=(5, 5))

Before:

image

After:

image

Other things that are new

I've also added parameters to clustermap to allow to change the size of dendrogram and colors.

Unfortunately I didn't manage to fix clustermaps with square=True, these are still broken beyond repair.

@lukauskas
Copy link
Contributor Author

@mwaskom , do you know what is happening here?

This is an odd place for the tests to fail as I did not touch color palettes...

=================================== FAILURES ===================================
____________________ TestColorPalettes.test_get_color_cycle ____________________
self = <seaborn.tests.test_palettes.TestColorPalettes object at 0x2af46b1cbed0>
    def test_get_color_cycle(self):
        with warnings.catch_warnings():
            warnings.simplefilter('ignore')
            result = utils.get_color_cycle()
>           expected = mpl.rcParams['axes.color_cycle']
seaborn/tests/test_palettes.py:296: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
self = RcParams({'_internal.classic_mode': False,
          'agg.path.chunksize': 0,
...e': False,
          'ytick.minor.width': 0.5,
          'ytick.right': False})
key = 'axes.color_cycle'
    def __getitem__(self, key):
        inverse_alt = None
        if key in _deprecated_map:
            alt_key, alt_val, inverse_alt = _deprecated_map[key]
            warnings.warn(self.msg_depr % (key, alt_key),
                          mplDeprecation)
            key = alt_key
    
        elif key in _deprecated_ignore_map:
            alt = _deprecated_ignore_map[key]
            warnings.warn(self.msg_depr_ignore % (key, alt),
                          mplDeprecation)
            key = alt
    
        elif key in _obsolete_set:
            warnings.warn(self.msg_obsolete % (key, ),
                          mplDeprecation)
            return None
    
>       val = dict.__getitem__(self, key)
E       KeyError: 'axes.color_cycle'
../../../miniconda/envs/testenv/lib/python2.7/site-packages/matplotlib/__init__.py:950: KeyError

@lukauskas
Copy link
Contributor Author

This fixes #437

@mwaskom
Copy link
Owner

mwaskom commented Mar 29, 2018

@mwaskom , do you know what is happening here?

Matplotlib changed the color_cycle to prop_cycle a while back and must have just dropped the old name completely. I have no idea what that test was trapping warnings, which otherwise would probably have made it clear that this was happening...

@lukauskas
Copy link
Contributor Author

Sorry about the radio silence in the last few days.

@mwaskom - do you want me to fix this test?

@mwaskom
Copy link
Owner

mwaskom commented Apr 11, 2018

@mwaskom - do you want me to fix this test?

No that shouldn't be part of this PR

@mwaskom
Copy link
Owner

mwaskom commented Jun 1, 2018

See #1443

@dburkhardt
Copy link

What's the status on this PR? I would love to have access to these features!

@asalt
Copy link

asalt commented Feb 13, 2019

What's the status on this PR? I would love to have access to these features!

@dburkhardt
Looks like in limbo while the future of clustermap and heatmap are in transition (see #1443 ). However, it's pretty easy to simply copy/paste the added functionality from this pull request into your own code. It's all pure Python, and easy to put into your own projects as an importable class.

class MyCluserGrid(seaborn.matrix.Clustergrid):
    def new_or_updated_function():
        # new code

This is probably easier than forking the entire repo.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants