在seaborn stripplot中更改轴刻度,其中x值是时间戳。

时间:2017-11-15 08:52:55

标签: python matplotlib seaborn

研究员数据,

我想使用seaborn功能绘制数据帧中的数据并更改x轴刻度。

我这样读了数据

import pandas as pd

with open(f) as fi:
    df = pd.read_csv(fi, delimiter=';', parse_dates = ['date'])
df.date = df.date.apply(lambda x: x.date())#removing time, only date remains

dataframe有三列对此问题很重要: df.datedf.sedimentationdf.label

df.date的格式为yyyy-mm-dd 并且日期对象的类型为:datetime.date

df.sedimentation的类型为:numpy.float64

df.label的类型为:str

我将数据绘制如下:

import matplotlib.pyplot as plt
import seaborn as sns

fig, ax = plt.subplots(figsize = figsize)

sns.set_style( "darkgrid")

ax.set_title(title)
ax = sns.stripplot(data = df, x = 'date', y = 'sedimentation', hue = 'label')    
ax.set_ylim([-90,100])

plt.legend(ncol = 3, bbox_to_anchor=(1, 1), loc="upper left")

plt.show()

这给出了以下图像:

Seaborn Image 1

但是,x轴上的刻度仅显示数据框df中给出的值。我希望有一个连续的x轴显示每年的所有月份。数据点df.sedimentation显示在x轴的正确点上。

所以我添加以下内容:

import matplotlib.dates as mdates

years = mdates.YearLocator()   # set yearly ticker 
months = mdates.MonthLocator()  # set monthly ticker 
yearsFmt = mdates.DateFormatter('\n\n%Y') # set format for year 
monthsFmt = mdates.DateFormatter('%b') # set format for month 

ax.xaxis.set_major_locator(years) 
ax.xaxis.set_major_formatter(yearsFmt)
ax.xaxis.set_minor_locator(months)
ax.xaxis.set_minor_formatter(monthsFmt)

datemin = dt.date(df.date.min().year, 1, 1)
datemax = dt.date(df.date.max().year + 1, 1, 1)
ax.set_xlim(datemin, datemax)

但这是一些奇怪的魔法发生,我不明白,我得到这个形象:

Seaborn Image 2

我得到了一个漂亮的x轴自动收录机,但我的数据没有显示......

所以我想,也许有两个不同的轴对象。一个在这里:

fig, ax = plt.subplots(figsize = figsize),其中一个:

ax = sns.stripplot(data = df, x = 'date', y = 'sedimentation', hue = 'label')

所以我想我会将轴对象ax添加到此:

ax = sns.stripplot(data = df, ax = ax, x = 'date', y = 'sedimentation', hue = 'label')

但是这没用。我完全没有使用seaborn,只是使用matplotlibpandas``groupby functionality找到了解决方法。但我想使用seaborn,因为我对hue功能特别感兴趣。

我的问题是:为什么在我改变xaxis滴答时数据没有显示?我怎样才能让我的数据显示在轴对象上但仍然有我想要的刻度?

1 个答案:

答案 0 :(得分:1)

stripplot是一个分类图。正如the documentation所说:

  

绘制一个散点图,其中一个变量是分类的。

因此,您的日期显示为类别(即每个整数的一个日期,轴的范围从0len(categories)-1)。您的第一个类别是" 2016-01-29",它将显示在轴上的位置0。您的第二个类别是" 2016-05-18",它显示在轴上的位置1,依此类推。

为了在轴上显示实际日期,请不要使用任何分类图。相反,plt.scatter可能是一种选择。

from datetime import datetime
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

rd = lambda : datetime(2017,np.random.randint(1,13),np.random.randint(1,29))
cats = ["Category {}".format(i) for i  in list("ABCD")]
df = pd.DataFrame({"date" : [rd() for i in range(29)],
                   "y" : np.random.rand(29),
                   "category" : np.random.choice(cats,size=29)})

dates = [d.to_pydatetime() for d in df["date"]]
u, c = np.unique(df["category"], return_inverse=True)

sc = plt.scatter(dates, df["y"], c=plt.cm.tab10(c))

scmap = lambda i: plt.plot([],[], marker="o",ls="none", c=plt.cm.tab10(i))[0]
plt.legend(handles=[scmap(i) for i in range(len(u))], 
           labels=list(u))
plt.gcf().autofmt_xdate()
plt.show()

enter image description here

<小时/> 或者使用seaborn,您可以使用FacetGrid映射到plt.scatter图,例如可以使用hue参数。

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

rd = lambda : datetime(2017,np.random.randint(1,13),np.random.randint(1,29))
cats = ["Category {}".format(i) for i  in list("ABCD")]
df = pd.DataFrame({"date" : pd.Series([rd() for i in range(29)], dtype=object),
                   "y" : np.random.rand(29),
                   "category" : np.random.choice(cats,size=29)})


g = sns.FacetGrid(df, hue="category", size=3, aspect=2)
g.map(plt.scatter, "date", "y").add_legend()

plt.show()

enter image description here