Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Artificial tick labels for seaborn heatmaps

I have a seaborn heatmap that looks like this:

enter image description here

...generated from a pandas dataframe of randomly generated values a piece of which looks like this:

enter image description here

The values along the y axis are all in the range [0,1], and the ones on the x axis in the range [0,2*pi], and I just want some short floats at regular intervals for my tick labels, but I can only seem to get values that are in my dataframe. When I try specifying the values I want, it doesn't put them in the right place, as seen in the plot above. He's my code right now. How can I get the axis labels that I tried specifying with xticks and yticks in this code in the correct places (which would be evenly spaced along the axes)?

import pandas as pd
import numpy as np
import matplotlib as plt
from matplotlib.mlab import griddata

sns.set_style("darkgrid")
PHI, COSTH = np.meshgrid(phis, cos_thetas)
THICK = griddata(phis, cos_thetas, thicknesses, PHI, COSTH, interp='linear')

thick_df = pd.DataFrame(THICK, columns=phis, index=cos_thetas)
thick_df = thick_df.sort_index(axis=0, ascending=False)
thick_df = thick_df.sort_index(axis=1)

cmap = sns.cubehelix_palette(start=1.6, light=0.8, as_cmap=True, reverse=True)

yticks = np.array([0,0.2,0.4,0.6,0.8,1.0])

xticks = np.array([0,1,2,3,4,5,6])

g = sns.heatmap(thick_df, linewidth=0, xticklabels=xticks, yticklabels=yticks, square=True, cmap=cmap)

plt.show(g)
like image 992
Arnold Avatar asked Nov 22 '16 05:11

Arnold


1 Answers

Here's something that should do what you want:

cmap = sns.cubehelix_palette(start=1.6, light=0.8, as_cmap=True, reverse=True)

yticks = np.linspace(0,1,6)

x_end = 6
xticks = np.arange(x_end+1)

ax = sns.heatmap(thick_df, linewidth=0, xticklabels=xticks, yticklabels=yticks[::-1], square=True, cmap=cmap)

ax.set_xticks(xticks*ax.get_xlim()[1]/(2*math.pi))
ax.set_yticks(yticks*ax.get_ylim()[1])

plt.show()

Seaborn heatmap

You could pass ['{:,.2f}'.format(x) for x in xticks] instead of xticks to get a float with 2 decimals.

Note that I'm reversing the yticklabels because that's what seaborn does: see matrix.py#L138.

Seaborn calculates the tick positions around the same place (e.g.: #L148), for you that amounts to:

# thick_df.T.shape[0] = thick_df.shape[1]
xticks: np.arange(0, thick_df.T.shape[0], 1) + .5
yticks: np.arange(0, thick_df.T.shape[1], 1) + .5
like image 199
Julien Marrec Avatar answered Oct 18 '22 23:10

Julien Marrec