Search code examples
pandasnumpymatplotlibcolorbarimshow

Plot a 2D Colormap/Heatmap in matplotlib with x y z data from a pandas dataframe


I have a pandas dataframe which looks like this

X Y Z
-1 -1 123
-1 0 456
-1 1 678
0 -1 124
0 0 890
0 1 121
1 -1 767
1 0 987
1 1 450
  • The actual size is (121,3)

I would like to plot a 2D colourmap where the X and Y are on the x,y axes and the Y shows the intensity of the value as a colourbar on the right side of the plot.

Note that here the values of the column Z are not a function of X and Y.

I tried to convert this dataframe into a numpy array. I'm having trouble creating a Z mesh with a the size of (121,121) when I do not have a dependency of the Z on the X and Y. I've tried using imshow and pcolor and looked at other similar answers but I coudn't find anything.


Solution

  • The most straightforward approach would be Seaborn's heatmap:

    import matplotlib.pyplot as plt
    import seaborn as sns
    import pandas as pd
    from io import StringIO
    
    data_str = '''-1    -1  123
    -1  0   456
    -1  1   678
    0   -1  124
    0   0   890
    0   1   121
    1   -1  767
    1   0   987
    1   1   450'''
    df = pd.read_csv(StringIO(data_str), names=['x', 'y', 'z'], delim_whitespace=True)
    df_pivoted = df.pivot(columns='x', index='y', values='z')
    ax = sns.heatmap(data=df_pivoted, annot=True, fmt='d', cmap='RdYlGn', cbar=True, cbar_kws={'label': 'z'}, square=True)
    ax.tick_params(labelrotation=0)
    plt.show()
    

    sns.heatmap