1

I have plotted a heatmap which is displayed below. on the xaxis it shows time of the day and y axis shows date. I want to show xaxis at every hour instead of the random xlabels it displays here.enter image description here

I tried following code but the resulting heatmap overrites all xlabels together:

t = pd.date_range(start='00:00:00', end='23:59:59', freq='60T').time
df = pd.DataFrame(index=t)
df.reset_index(inplace=True)
df['index'] = df['index'].astype('str')
sns_hm = sns.heatmap(data=mat, cbar=True, lw=0,cmap=colormap,xticklabels=df['index'])

enter image description here

Kathan Vyas
  • 355
  • 3
  • 16
  • No they are not. – Kathan Vyas Mar 18 '22 at 20:14
  • but that is where my problem comes. The original dataframe has nearly 86400 values as it is every second for each day. I just want to display labels for every hour which will come to 24 values per day. How do I do it? – Kathan Vyas Mar 18 '22 at 20:26
  • Note that the heatmaps ticks are always categorical, internally numbered 0,1,2,.... If you need something else, there is matplotlib's `imshow` or `pcolor`. – JohanC Mar 18 '22 at 20:26
  • @GreyMurav I have to preserve the data frame and cant mess with it. that is why I went to this approach. Isnt there a way I could use this approach with changes? – Kathan Vyas Mar 18 '22 at 20:49
  • @GreyMurav also, i tried through your way. The whole issue with me using this alternative approach was because having 18k points, its taking too much time for generating the plot. That is why I reduced the number of ticks from 18k to 24. but if I create a new column with similar length, it defeats my purpose as it will take similar time. – Kathan Vyas Mar 18 '22 at 20:57
  • How did you create your original plot? How is `mat` structured? Is there one entry every second? Is `mat` a dataframe? Could you create some artificial test data to make this reproducible? – JohanC Mar 19 '22 at 01:04
  • I figured it out. Wil post a soln soon – Kathan Vyas Mar 19 '22 at 01:15

1 Answers1

2

The following code supposes mat is a dataframe with columns for some timestamps for each of a number of days. Each of the days, the same timestamps need to appear again.

After drawing the heatmap, the left and right limits of the x-axis are retrieved. Supposing these go from 0 to 24 hour, the range can be subdivided into 25 positions, one for each of the hours.

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
from pandas.tseries.offsets import DateOffset
from matplotlib.colors import ListedColormap, to_hex

# first, create some test data
df = pd.DataFrame()
df["date"] = pd.date_range('20220304', periods=19000, freq=DateOffset(seconds=54))
df["val"] = (((np.random.rand(len(df)) ** 100).cumsum() / 2).astype(int) % 2) * 100
df['day'] = df['date'].dt.strftime('%d-%m-%Y')
df['time'] = df['date'].dt.strftime('%H:%M:%S')

mat = df.pivot(index='day', columns='time', values='val')

colors = list(plt.cm.Greens(np.linspace(0.2, 0.9, 10)))
ax = sns.heatmap(mat, cmap=colors, cbar_kws={'ticks': range(0, 101, 10)})
xmin, xmax = ax.get_xlim()
tick_pos = np.linspace(xmin, xmax, 25)
tick_labels = [f'{h:02d}:00:00' for h in range(len(tick_pos))]
ax.set_xticks(tick_pos)
ax.set_xticklabels(tick_labels, rotation=90)
ax.set(xlabel='', ylabel='')

plt.tight_layout()
plt.show()

The left plot shows the default tick labels, the right plot the customized labels.

sns.heatmap, setting xtick labels per hour

JohanC
  • 71,591
  • 8
  • 33
  • 66