Python 更改seaborn StripPlot中的轴刻度,其中x值是时间戳。

Python 更改seaborn StripPlot中的轴刻度,其中x值是时间戳。,python,matplotlib,seaborn,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有三列对于此问题非常重

数据呆子们

我想使用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.日期
df.沉淀
df.标签

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

df.disposition
类型为:
numpy.float64

df.标签的类型为:
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()
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)
这将显示以下图像:

但是,x轴上的记号仅显示数据框
df
中给出的值。我想要一个连续的x轴,显示每年的所有月份。在x轴的正确点处显示
df.deposition
的数据点

因此,我补充如下:

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()
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)
但这里有一些奇怪的魔法发生了,我不明白,我得到了这个图像:

我得到了一个漂亮的x轴计时器,但我的数据没有显示…

所以我想,可能有两个不同的轴对象。这里有一个:

fig,ax=plt.子批次(figsize=figsize)
这里有一个:

ax=sns.stripplot(数据=df,x='date',y='沉淀',色调='label')

所以我想我应该把axes对象
ax
添加到这个:

ax=sns.stripplot(数据=df,ax=ax,x='date',y='沉淀',色调='label')

但这并不奏效。我找到了一个解决办法,根本不使用
seaborn
,只使用
matplotlib
pandas``groupby
。但是我想使用
seaborn
,因为我对
hue
功能特别感兴趣


因此,我的问题是:为什么在我更改xaxis刻度时数据不显示?我如何才能让数据显示在Axis对象上,同时仍然具有我想要的刻度?A
stripplot
是一种分类图。正如上面所说:

画一个散点图,其中一个变量是分类变量

因此,您的日期显示为类别(即每个整数有一个日期,轴的范围为
0
len(类别)-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()


或者使用seaborn,您可以使用
FaceGrid
映射到
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()

A
stripplot
是一种分类图。正如上面所说:

画一个散点图,其中一个变量是分类变量

因此,您的日期显示为类别(即每个整数有一个日期,轴的范围为
0
len(类别)-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()


或者使用seaborn,您可以使用
FaceGrid
映射到
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()

条带图是分类图。您的日期显示为类别(即,每个整数有一个日期,轴的范围从0到len(类别))。为了在轴上有真实的日期,不要使用任何分类图。相反,
plt.scatter
可能是一种选择。谢谢你,王尔德先生,不过,我更愿意继续使用seaborn,因为它的功能更便于以后的分析。此外,我只是想了解为什么它不起作用。我的评论解释了为什么它不起作用。因此,即使你愿意,也不能使用分类情节。嗯,我不理解你的评论。您只说明我正在显示类别,为了获得真实日期,我应该使用
plt.scatter
。我没有变得更聪明…你的第一个类别是“2016-01-29”,它将显示在轴上的位置0。第二类是“2016-05-18”,显示在轴上的位置1处,依此类推。轴的范围从0到类别数1。条带图是分类图。您的日期显示为类别(即,每个整数有一个日期,轴的范围从0到len(类别))。为了在轴上有真实的日期,不要使用任何分类图。相反,
plt.scatter
可能是一种选择。谢谢你,王尔德先生,不过,我更愿意继续使用seaborn,因为它的功能更便于以后的分析。此外,我只是想了解为什么它不起作用。我的评论解释了为什么它不起作用。因此,即使你愿意,也不能使用分类情节。嗯,我不理解你的评论。您只说明我正在显示类别,为了获得真实日期,我应该使用
plt.scatter
。我没有变得更聪明…你的第一个类别是“2016-01-29”,它将显示在轴上的位置0。第二类是“2016-05-18”,显示在轴上的位置1处,依此类推。你的坐标轴范围从0到类别的数量-1。太棒了!感谢您解释这个概念,并展示了仍然使用seaborn的可能性。太好了!感谢您解释这个概念,并展示了仍然使用seaborn的可能性。