Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding spacing in heatmaps of python altair plots

Tags:

python

altair

Is it possible to add some spacing in the heatmaps created by using mark_rect() in Altair python plots? The heatmap in figure 1 will be converted to the one in figure 2. You can assume that this is from a dataframe and each column corresponds to a variable. I deliberately drew the white bars like this to avoid any hardcoded indexed solution. Basically, I am looking for a solution where I can provide the column name and/or the index name to get white spacings drawn both vertically and/or horizontally.

enter image description here

enter image description here

like image 859
ilyas Avatar asked Jul 21 '19 23:07

ilyas


People also ask

How to plot a heatmap in Python?

In this article, we learn to plot a heatmap in Python. They are different methods to plot heatmap imshow () function in matplotlib.pyplot help to plot heatmap The pcolormesh () function in the pyplot module of the matplotlib library is used to create a pseudo-color map with an irregular rectangular grid.

How do I use Altair to create a correlation heatmap?

When we click on the correlation heatmap, Altair tracks which of the variables has been selected, for example Precip_hrmax and Rel_humid. Next we need to update the 2d histogram. A quirk of Altair is that we can only subset based on rows, not columns.

How to work with Altair and large amounts of data?

How to work with Altair and large amounts of data by aggregating the data in a 2d histogram. How to sort the values on a categorical axis using numerical values in the same data in Altair. This is particularly useful when the data changes dynamically and you cannot precompute how the values should be sorted.

What is the best Python plotting framework for interacitivity?

Luck would have it that an article on Medium pointed me to a plotting framework that specializes in interacitivity: Altair. Altair is a declarative statistical visualization library for Python, based on Vega and Vega-Lite.


2 Answers

You can specify the spacing within heatmaps using the scale.bandPaddingInner configuration parameter, which is a number between zero and one that specifies the fraction of the rectangle mark that should be padded, and defaults to zero. For example:

import altair as alt
import numpy as np
import pandas as pd

# Compute x^2 + y^2 across a 2D grid
x, y = np.meshgrid(range(-5, 5), range(-5, 5))
z = x ** 2 + y ** 2

# Convert this grid to columnar data expected by Altair
source = pd.DataFrame({'x': x.ravel(),
                     'y': y.ravel(),
                     'z': z.ravel()})

alt.Chart(source).mark_rect().encode(
    x='x:O',
    y='y:O',
    color='z:Q'
).configure_scale(
    bandPaddingInner=0.1
)

enter image description here

like image 150
jakevdp Avatar answered Sep 22 '22 23:09

jakevdp


One way to create these bands would be to facet the chart using custom bins. Here is a way to do that, using pandas.cut to create the bins.

import pandas as pd
import altair as alt

df = (pd.util.testing.makeDataFrame()
      .reset_index(drop=True)  # drop string index
      .reset_index()  # add an index column
      .melt(id_vars=['index'], var_name="column"))

# To include all the indices and not create NaNs, I add -1 and max(indices) + 1 to the desired bins.
bins= [-1, 3, 9, 15, 27, 30]
df['bins'] = pd.cut(df['index'], bins, labels=range(len(bins) - 1))
# This was done for the index, but a similar approach could be taken for the columns as well.

alt.Chart(df).mark_rect().encode(
    x=alt.X('index:O', title=None),
    y=alt.Y('column:O', title=None),
    color="value:Q",
    column=alt.Column("bins:O", 
                      title=None, 
                      header=alt.Header(labelFontSize=0))
).resolve_scale(
    x="independent"           
).configure_facet(
    spacing=5
)

enter image description here

Note the resolve_scale(x='independent') to not repeat the axis in each facet, and thhe spacing parameter in configure_facet to control the width of the spacing. I set labelFontSize=0 in the header so that we do not see the bins names on top of each facet.

like image 29
FlorianGD Avatar answered Sep 19 '22 23:09

FlorianGD