Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to edit datetime format on Seaborn heatmap without changing the date?

I am working with satellite data with which I extract velocities of points over several decades. I have a dataframe with datetime index, and my velocities in columns (each column represents 1 point). The database is widely incomplete, and the points do not necessarily have values at the same time as the others.

I plotted a heatmap with seaborn which works, but the datetime displays too much information (I only want "YYYY-MM-DD". However when I compute the line ax.yaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d') ) the dates are not correct anymore. How can I solve this issue ? (The second plot shows how it is correctly displayed when the DateFormatter line is commented out).

import numpy as np
from matplotlib import pyplot as plt
import pandas as pd
import seaborn as sns
import matplotlib.dates as mdates

v1 = np.array([1671., 1756.,   1704., 1574., 1589.,   1772.,   1652., 1778., 1719.,
             1699.], dtype=float)
    
dv1 = np.array(['2015-01-21T00:00:00.032000000', '2015-01-29T00:00:00.016000000',
           '2014-06-11T00:00:00.544000000', '2014-12-20T00:00:00.160000000',
           '2014-12-28T00:00:00.144000000', '2015-01-05T00:00:00.192000000',
           '2014-07-29T00:00:00.512000000', '2015-03-02T00:00:00.080000256',
           '2015-07-08T00:00:00.112000000', '2015-08-25T00:00:00.272000000'],
          dtype='datetime64[ns]')
    
v2 = np.array([1647., 1758., 1722.], dtype=float)
    
dv2 = np.array(['2015-08-10T00:00:00.032000000', '2015-02-18T00:00:00.016000000',
           '2014-09-19T00:00:00.544000000'],
          dtype='datetime64[ns]')

df1 = pd.DataFrame({'Velocity0': v1}, index=pd.to_datetime(dv1))

df2 = pd.DataFrame({'Velocity1': v2}, index=pd.to_datetime(dv2))

df1 = df1.append(df2)

df1 = df1.sort_index()

df1 = df1.sort_index()

plt.figure(figsize=(15,15))
ax = sns.heatmap(df1)
for item in ax.get_yticklabels():
    item.set_rotation(0)

for item in ax.get_xticklabels():
    item.set_rotation(90)
    
ax.yaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d') )

plt.figure(figsize=(15,15))
plt.rcParams.update({'font.size': 20})
plt.plot(df1)

Seaborn plot with wrong dates Same plot with correct dates but wrong format

like image 635
Nihilum Avatar asked Nov 14 '25 14:11

Nihilum


1 Answers

For the mdates DateFormatter to work you would need to have a continuous time scale on the y-axis based on matplotlib date units. The problem is that the x and y-axis of seaborn heatmaps use ranges of integers. You can check the y-axis units by printing the tick locations:

print(ax.get_yticks())
# [ 0.5  1.5  2.5  3.5  4.5  5.5  6.5  7.5  8.5  9.5 10.5 11.5 12.5]

This is why the DateFormatter has no effect. Instead, you can format the labels by using the strftime method with the DatetimeIndex:

import numpy as np     # v 1.19.2
import pandas as pd    # v 1.1.3
import seaborn as sns  # v 0.11.0

v1 = np.array([1671., 1756., 1704., 1574., 1589., 1772., 1652., 1778., 1719., 1699.])
dv1 = np.array(['2015-01-21T00:00:00.032000000', '2015-01-29T00:00:00.016000000',
                '2014-06-11T00:00:00.544000000', '2014-12-20T00:00:00.160000000',
                '2014-12-28T00:00:00.144000000', '2015-01-05T00:00:00.192000000',
                '2014-07-29T00:00:00.512000000', '2015-03-02T00:00:00.080000256',
                '2015-07-08T00:00:00.112000000', '2015-08-25T00:00:00.272000000'],
               dtype='datetime64[ns]')
    
v2 = np.array([1647., 1758., 1722.], dtype=float)
dv2 = np.array(['2015-08-10T00:00:00.032000000', '2015-02-18T00:00:00.016000000',
                '2014-09-19T00:00:00.544000000'],
               dtype='datetime64[ns]')

df1 = pd.DataFrame({'Velocity0': v1}, index=dv1)
df2 = pd.DataFrame({'Velocity1': v2}, index=dv2)
df1 = df1.append(df2).sort_index()

ax = sns.heatmap(df1)
ax.figure.set_size_inches(6,6)
ticklabels = [df1.index[int(tick)].strftime('%Y-%m-%d') for tick in ax.get_yticks()]
ax.set_yticklabels(ticklabels);

heatmap

like image 119
Patrick FitzGerald Avatar answered Nov 17 '25 03:11

Patrick FitzGerald



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!