Search code examples
pythonpandasjupyter-notebookaltair

How do I stop the scatter plot from whiting out the heatmap when I overlay them in Altair?


So I want to overlay a heatmap with a scatter plot. I've managed to create the subplots and to overlay them, but when I overlay them the scatter plot whites out the columns and rows of each of the nodes it scatters when displayed on the heatmap. Here is my code:

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

#Generating scatter data
x = []
y = []
for i in range(5):
    x.append(r.uniform(-10,10))
    y.append(r.uniform(-10,10))
source1 = pd.DataFrame({
    'y' : y,
    'x' : x
})

#Scatter plot
scatter1 = alt.Chart(source1).mark_point().encode(
    x = alt.X('x:O', axis=alt.Axis(labels=False)),
    y = alt.Y('y:O', axis=alt.Axis(labels=False)),
).properties(
    width=400,
    height=400,
)

#Generating heatmap data
X, Y = np.meshgrid(range(-10,10), range(-10,10))
Z = X**2 - Y**2 

source2 = pd.DataFrame({
    'X': X.ravel(),
    'Y': Y.ravel(),
    'Z': Z.ravel()
})

#Heatmap
heatmap1 = alt.Chart(source2).mark_rect().encode(
    x='X:O',
    y='Y:O',
    color='Z:Q'
).properties(
    width=400,
    height=400
)

#Overlay
alt.layer(scatter1, heatmap1)

I want the nodes of the scatter plot to be displayed over the heatmap but without the heatmap being changed at all. How do I do this?

Thanks in advance! :)


Solution

  • From what I could understand, there is a mismatch between the ticks of the heatmap and the scatter plot. Therefore, it creates a white cross around scatter plot points.

    I modified your code test this as follows:

    source1 =source2.sample(5).drop(columns='Z')
    
    #Scatter plot
    scatter1 = alt.Chart(source1).mark_point(color='red').encode(
        x = alt.X('X:O', axis=alt.Axis(labels=False)),
        y = alt.Y('Y:O', axis=alt.Axis(labels=False)),
    ).properties(
        width=400,
        height=400,
    )
    
    #Heatmap
    heatmap1 = alt.Chart(source2).mark_rect().encode(
        x='X:O',
        y='Y:O',
        color='Z:Q'
    ).properties(
        width=400,
        height=400
    )
    alt.layer(heatmap1,scatter1)
    

    Here the data points for the scatter plot are a random sample from the heatmap data. This ensures that the x and y are subsets of the ticks in the heatmap. This gives a plot like this

    enter image description here

    You can consider rounding off the scatter plot data to the nearest heatmap point.