question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Categorical heatmap hack - how to add row-titles?

See original GitHub issue

Aim

I am looking to make a categorical heatmap, made up of individual strips with different categorical columns in a dataframe, somewhat similar to this figure: image taken from this paper.

What I need help with

I cannot figure out how to add row labels to the heatmap.

Making the heatmap

I use mark_rect and only give it an x and a color. Then I remove the legend, vconcat and remove the spacing between the individual plots. The legend would provide the row label I am looking for but I have to remove it, otherwise I cannot put the individual heatmap strips together tightly.

Making the legends

For the legends, I do the same as for the heatmap, except I don’t give an x in encode(), just a color.

Configuring

Finally, I configure_concat to make the heatmap strips snugg and configure_view to remove the outline of the empty plots that each of the legends comes with.

import pandas as pd
import altair as alt
#### Generating some Data ####
source = pd.DataFrame(
    {'fruits':['apple', 'banana', 'orange'], 
     'shape':['round', 'long', 'round'], 
     'weight':[0.3, 0.1, 0.25]})
#### Making the Heatmap ####
heatmap = alt.vconcat(
    alt.Chart(source).mark_rect().encode(
        x = alt.X('fruits', axis=None),
        color = alt.Color('shape', legend=None),
    ),
    alt.Chart(source).mark_rect().encode(
        x = 'fruits',
        color = alt.Color('weight', legend=None),
    )
)
#### Making the Legends ####
legends = alt.vconcat(
    alt.Chart(source).mark_rect(
        fillOpacity=0, 
        strokeOpacity=0
    ).encode(
        color = alt.Color('shape'),
    ), 
     alt.Chart(source).mark_rect(
        fillOpacity=0, 
        strokeOpacity=0
    ).encode(
        color = alt.Color('weight'),
    ), 
)

#### Configuring the concat ####
(
    heatmap | legends
).configure_concat(spacing=0 #makes strips of heatmap snugg
).configure_view(strokeOpacity=0) #removes plot border for the empty plots with the legends

This gives me the following heatmap: visualization (3)

Adding Row labels

The row labels here should be 'shape' and 'weight' but I cannot get that to work. My idea was to use the title as a row label with orient='left' and angle=90 but that doesn’t seem to work.

alt.Chart(source, title="shape").mark_rect().encode(
        x = alt.X('fruits', axis=None),
        color = alt.Color('shape', legend=None),
).configure_title(
    orient='left',
    angle=90
)

visualization (4)

I don’t think I understand what the angle argument does in configure_title, because it doesn’t seem to rotate the title text, whether I give orient or not. From the docstring of configure_title:

angle : float Angle in degrees of title and subtitle text.

Thanks

Thank you for all the awesomeness in altair, the library is a true delight!

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:7 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
jakevdpcommented, Jun 5, 2020

Unless you reference the calculation in an encoding, it will not be used in the chart:

alt.Chart(example_data).mark_rect().encode(
        x = alt.X('fruits'),
        y = alt.Y('y:N', title=None),
        color = alt.Color('shape'),
    ).transform_calculate(
    y='"shape"'
)
1reaction
jakevdpcommented, Jun 4, 2020

One way to do this kind of thing is to use a fold transform, and then use either a row encoding or a y-encoding; something like this:

import altair as alt
import pandas as pd

source = pd.DataFrame(
    {'fruits':['apple', 'banana', 'orange'], 
     'shape':['round', 'long', 'round'], 
     'weight':[0.3, 0.1, 0.25]})

alt.Chart(source).transform_fold(
    ["shape", "weight"]
).mark_rect().encode(
    x='fruits:N',
    y='key:N',
    color=alt.Color('value:N', legend=None)
)

visualization (4)

This only works if you’re OK with all values being represented by the same color scale.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Confusion Matrix Visualization - Medium
How to add a label and percentage to a confusion matrix plotted using a Seaborn heatmap. Plus some additional options.
Read more >
Ultimate Guide to Heatmaps in Seaborn with Python
In this tutorial, we'll cover everything you need to know from basic to advanced usage of Heatmaps in Seaborn and Python.
Read more >
Categorical Variable Analysis - JulienBeaulieu - GitBook
One alternative way of depicting the relationship between two categorical variables is through a heat map. Heat maps were introduced earlier as the...
Read more >
How to express classes on the axis of a heatmap in Seaborn
It's a bit of a hack, but it will work. First, we'll load the sample data and do a bit of roundabout transformations...
Read more >
Heat Maps for multiple dimensions - Tableau Community
As attached in the image, I am looking to create a heat map with multiple dimensions. ... Tableau Hack: How to Conditionally Format...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found