Show dates on seaborn heatmap

帅比萌擦擦* 提交于 2019-12-29 08:20:34

问题


I am trying to create a heat map from pandas dataframe using seaborn library. Here, is the code:

test_df = pd.DataFrame(np.random.randn(367, 5), 
                 index = pd.DatetimeIndex(start='01-01-2000', end='01-01-2001', freq='1D'))

ax = sns.heatmap(test_df.T)
ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_minor_locator(mdates.DayLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))
ax.xaxis.set_minor_formatter(mdates.DateFormatter('%d'))

However, I am getting a figure with nothing printed on the x-axis.


回答1:


Seaborn heatmap is a categorical plot. It scales from 0 to number of columns - 1, in this case from 0 to 366. The datetime locators and formatters expect values as dates (or more precisely, numbers that correspond to dates). For the year in question that would be numbers between 730120 (= 01-01-2000) and 730486 (= 01-01-2001).

So in order to be able to use matplotlib.dates formatters and locators, you would need to convert your dataframe index to datetime objects first. You can then not use a heatmap, but a plot that allows for numerical axes, e.g. an imshow plot. You may then set the extent of that imshow plot to correspond to the date range you want to show.

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

df = pd.DataFrame(np.random.randn(367, 5), 
                 index = pd.DatetimeIndex(start='01-01-2000', end='01-01-2001', freq='1D'))

dates = df.index.to_pydatetime()
dnum = mdates.date2num(dates)
start = dnum[0] - (dnum[1]-dnum[0])/2.
stop = dnum[-1] + (dnum[1]-dnum[0])/2.
extent = [start, stop, -0.5, len(df.columns)-0.5]

fig, ax = plt.subplots()
im = ax.imshow(df.T.values, extent=extent, aspect="auto")

ax.xaxis.set_major_locator(mdates.MonthLocator())
ax.xaxis.set_minor_locator(mdates.DayLocator())
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b'))

fig.colorbar(im)
plt.show()




回答2:


I found this question when trying to do a similar thing and you can hack together a solution but it's not very pretty.

For example I get the current labels, loop over them to find the ones for January and set those to just the year, setting the rest to be blank.

This gives me year labels in the correct position.

xticklabels = ax.get_xticklabels()

for label in xticklabels:
    text = label.get_text()
    if text[5:7] == '01':
        label.set_text(text[0:4])
    else:
        label.set_text('')

ax.set_xticklabels(xticklabels)

Hopefully from that you can figure out what you want to do.



来源:https://stackoverflow.com/questions/45345177/show-dates-on-seaborn-heatmap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!