简体   繁体   English

热图中的日期轴 seaborn

[英]Date axis in heatmap seaborn

A little info: I'm very new to programming and this is a small part of the my first script.一点信息:我对编程很陌生,这是我第一个脚本的一小部分。 The goal of this particular segment is to display a seaborn heatmap with vertical depth on y-axis, time on x-axis and intensity of a scientific measurement as the heat function.此特定部分的目标是显示一个 seaborn 热图,y 轴为垂直深度,x 轴为时间,热函数为科学测量的强度。

I'd like to apologize if this has been answered elsewhere, but my searching abilities must have failed me.如果在其他地方已经回答了这个问题,我想道歉,但我的搜索能力一定让我失望。

sns.set()
nametag = 'Well_4_all_depths_capf'
Dp = D[D.well == 'well4']
print(Dp.date)


heat = Dp.pivot("depth",  "date", "capf")
### depth, date and capf are all columns of a pandas dataframe 

plt.title(nametag)

sns.heatmap(heat,  linewidths=.25)

plt.savefig('%s%s.png' % (pathheatcapf, nametag), dpi = 600)

this is the what prints from the ' print(Dp.date) ' so I'm pretty sure the formatting from the dataframe is in the format I want, particularly Year, day, month.这是从'print(Dp.date)'打印的内容,所以我很确定数据帧的格式是我想要的格式,特别是年、日、月。

0    2016-08-09
1    2016-08-09
2    2016-08-09
3    2016-08-09
4    2016-08-09
5    2016-08-09
6    2016-08-09
         ...    

But, when I run it the date axis always prints with blank times (00:00 etc) that I don't want.但是,当我运行它时,日期轴总是打印我不想要的空白时间(00:00 等)。 Is there a way to remove these from the date axis?有没有办法从日期轴中删除这些?

Is the problem that in a cell above I used this function to scan the file name and make a column with the date???问题是在上面的单元格中我使用此功能扫描文件名并使用日期制作一列吗??? Is it wrong to use datetime instead of just a date function?使用日期时间而不仅仅是日期函数是错误的吗?

D['date']=pd.to_datetime(['%s-%s-%s' %(f[0:4],f[4:6],f[6:8]) for f in             
D['filename']])

在此处输入图片说明

You have to use strftime function for your date series of dataframe to plot xtick labels correctly:您必须对数据框的日期系列使用 strftime 函数才能正确绘制 xtick 标签:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime, timedelta
import random

dates = [datetime.today() - timedelta(days=x * random.getrandbits(1)) for x in xrange(25)]
df = pd.DataFrame({'depth': [0.1,0.05, 0.01, 0.005, 0.001, 0.1, 0.05, 0.01, 0.005, 0.001, 0.1, 0.05, 0.01, 0.005, 0.001, 0.1, 0.05, 0.01, 0.005, 0.001, 0.1, 0.05, 0.01, 0.005, 0.001],\
 'date': dates,\
 'value': [-4.1808639999999997, -9.1753490000000006, -11.408113999999999, -10.50245, -8.0274750000000008, -0.72260200000000008, -6.9963940000000004, -10.536339999999999, -9.5440649999999998, -7.1964070000000007, -0.39225599999999999, -6.6216390000000001, -9.5518009999999993, -9.2924690000000005, -6.7605589999999998, -0.65214700000000003, -6.8852289999999989, -9.4557760000000002, -8.9364629999999998, -6.4736289999999999, -0.96481800000000006, -6.051482, -9.7846860000000007, -8.5710630000000005, -6.1461209999999999]})
pivot = df.pivot(index='depth', columns='date', values='value')

sns.set()
ax = sns.heatmap(pivot)
ax.set_xticklabels(df['date'].dt.strftime('%d-%m-%Y'))
plt.xticks(rotation=-90)

plt.show()

在此处输入图片说明

Example with standard heatmap datetime labels带有标准热图日期时间标签的示例

import pandas as pd
import seaborn as sns

dates = pd.date_range('2019-01-01', '2020-12-01')

df = pd.DataFrame(np.random.randint(0, 100, size=(len(dates), 4)), index=dates)

sns.heatmap(df)

标准热图

We can create some helper classes/functions to get to some better looking labels and placement.我们可以创建一些辅助类/函数来获得一些更好看的标签和位置。 AxTransformer enables conversion from data coordinates to tick locations, set_date_ticks allows custom date ranges to be applied to plots. AxTransformer支持从数据坐标到刻度位置的转换, set_date_ticks允许将自定义日期范围应用于绘图。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from collections.abc import Iterable
from sklearn import linear_model

class AxTransformer:
    def __init__(self, datetime_vals=False):
        self.datetime_vals = datetime_vals
        self.lr = linear_model.LinearRegression()
        
        return
    
    def process_tick_vals(self, tick_vals):
        if not isinstance(tick_vals, Iterable) or isinstance(tick_vals, str):
            tick_vals = [tick_vals]
            
        if self.datetime_vals == True:
            tick_vals = pd.to_datetime(tick_vals).astype(int).values
            
        tick_vals = np.array(tick_vals)
            
        return tick_vals
    
    def fit(self, ax, axis='x'):
        axis = getattr(ax, f'get_{axis}axis')()
        
        tick_locs = axis.get_ticklocs()
        tick_vals = self.process_tick_vals([label._text for label in axis.get_ticklabels()])
        
        self.lr.fit(tick_vals.reshape(-1, 1), tick_locs)
        
        return
    
    def transform(self, tick_vals):        
        tick_vals = self.process_tick_vals(tick_vals)
        tick_locs = self.lr.predict(np.array(tick_vals).reshape(-1, 1))
        
        return tick_locs
    
def set_date_ticks(ax, start_date, end_date, axis='y', date_format='%Y-%m-%d', **date_range_kwargs):
    dt_rng = pd.date_range(start_date, end_date, **date_range_kwargs)

    ax_transformer = AxTransformer(datetime_vals=True)
    ax_transformer.fit(ax, axis=axis)
    
    getattr(ax, f'set_{axis}ticks')(ax_transformer.transform(dt_rng))
    getattr(ax, f'set_{axis}ticklabels')(dt_rng.strftime(date_format))

    ax.tick_params(axis=axis, which='both', bottom=True, top=False, labelbottom=True)
    
    return ax

These provide us a lot of flexibility, eg这些为我们提供了很大的灵活性,例如

fig, ax = plt.subplots(dpi=150)

sns.heatmap(df, ax=ax)

set_date_ticks(ax, '2019-01-01', '2020-12-01', freq='3MS')

cleaned_heatmap_date_labels

or if you really want to get weird you can do stuff like或者如果你真的想变得奇怪,你可以做类似的事情

fig, ax = plt.subplots(dpi=150)

sns.heatmap(df, ax=ax)

set_date_ticks(ax, '2019-06-01', '2020-06-01', freq='2MS', date_format='%b `%y')

奇怪的热图日期标签

For your specific example you'll have to pass axis='x' to set_date_ticks对于您的具体示例,您必须将axis='x'传递给set_date_ticks

I had a similar problem, but the date was the index.我有一个类似的问题,但日期是索引。 I've just converted the date to string (pandas 1.0) before plotting and it worked for me.我刚刚在绘图之前将日期转换为字符串(pandas 1.0),它对我有用。

heat['date'] = heat.date.astype('string')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM