我无法将Seaborn中线条图的Xtick设置为相应小时的值

2024-06-16 09:55:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试了很多不同的方法,但我不能得到一个合理的xtick标签。这是我写的代码

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

#Line of Code just for importing the .csv Data
df = pd.read_csv('path of the csv file', sep=",", comment='#', decimal='.', parse_dates=True)

xticks = df.time.unique()


table = df.pivot_table("globalpower", index="time", aggfunc=np.mean)

graph = sns.lineplot(df.time, df.globalpower, data=df)
graph.set_xticks(range(0,24))
graph.set_xticklabels(['01:00','02:00','03:00','04:00','05:00','06:00','07:00','08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00','20:00','21:00','22:00','23:00','24:00' ])

我知道应该有一种更优雅的方式来列出一天中的时间

输出如下所示:

This is my current output

我打印了我的数据头,它看起来像这样:

Unnamed:    0      date      time  globalpower  voltage  globintensity  submetering1  submetering2  submetering3
0     1600236  1/1/2010  00:00:00        1.790   240.65            7.4           0.0           0.0          18.0
1     1600237  1/1/2010  00:01:00        1.780   240.07            7.4           0.0           0.0          18.0
2     1600238  1/1/2010  00:02:00        1.780   240.15            7.4           0.0           0.0          19.0
3     1600239  1/1/2010  00:03:00        1.746   240.26            7.2           0.0           0.0          18.0
4     1600240  1/1/2010  00:04:00        1.686   240.12            7.0           0.0           0.0          18.0

Tags: ofcsvtheimportdftimematplotlibas
2条回答

只是对Andrea的答案做了一点补充,只是解释一下我认为在您的原始代码中发生了什么。以下是具有分钟精度时间字符串和随机值的玩具数据:

In[0]:

import pandas as pd
import numpy as np
import seaborn as sns

times = []
for h in range(24):
    for m in range(60):
        times.append('{0}:{1}:00'.format(f'{h:02}',f'{m:02}'))

values = np.random.rand(1440*3)    #1400 minutes in a day

df = pd.DataFrame({'time':times*3,
                    'globalpower':values,})

df

Out[0]:
          time  globalpower
0     00:00:00     0.564812
1     00:01:00     0.429477
2     00:02:00     0.827994
3     00:03:00     0.525569
4     00:04:00     0.113478
       ...          ...
7195  23:55:00     0.624546
7196  23:56:00     0.981141
7197  23:57:00     0.096928
7198  23:58:00     0.170131
7199  23:59:00     0.398853

[7200 rows x 2 columns]

请注意,我每次重复3x,以便sns.lineplot对每个唯一的时间进行平均。用代码绘制此数据会产生与您描述的相同的错误:

graph = sns.lineplot(df.time, df.globalpower, data=df)
graph.set_xticks(range(0,24))
graph.set_xticklabels(['01:00','02:00','03:00','04:00','05:00','06:00','07:00','08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00','20:00','21:00','22:00','23:00','24:00'])

enter image description here

基本的差异在于打印函数和x轴参数都不知道有任何时间信息。当您使用x=df.timey=df.globalpower调用sns.lineplot时,seaborn基本上对每个唯一条目的时间列执行groupby操作,并平均全局幂值但在时间列中只能看到唯一的字符串,这些唯一的字符串在绘制时会进行排序,这恰好与一天中的时间顺序相匹配,因为它们是以字母数字的方式书写的

参见此,考虑使用一个EMH>非时间格式化字符串(例如‘0000’、‘0001’、‘0002’……’)<强>将导致同一图< /强>:

names = []
for h in range(24):
    for m in range(60):
        names.append(str(f'{h:02}') + str(f'{m:02}'))
#names = ['0001','0002','0003',...]

df2 = pd.DataFrame({'name':names*3,
                   'globalpower':values,})

graph2 = sns.lineplot(df2.name, df2.globalpower, data=df)
graph2.set_xticks(range(0,24))
graph2.set_xticklabels(['01:00','02:00','03:00','04:00','05:00','06:00','07:00','08:00','09:00','10:00','11:00','12:00','13:00','14:00','15:00','16:00','17:00','18:00','19:00','20:00','21:00','22:00','23:00','24:00'])

因此,当您使用tick参数时,说set_xticks(range(0,24))set_xticklabels(['01:00','02:00','03:00'...])基本上意味着“使用这24个标签在位置0到23处设置tick”,尽管绘图(在本例中)是1440个唯一的x值,因此0-23只跨越一小部分值

修复方法基本上就是Andrea所回答的:将您的时间信息转换成datetime格式,然后使用matplotlib.dates格式来设置节拍。对于您的时间字符串(无日期),您只需执行以下操作:

df['time'] = pd.to_datetime(df['time'])

然后跟着他们的答案走。这将在1970年1月1日给每一次完整的时间戳(在pandas中是默认的);但是,如果你只关心为每个重复出现的时间绘制一个平均24小时的周期,那么奇怪的一年并不重要

因为我无法访问您的数据,所以我创建了一个假的,以便处理一些数据。您只需使用df
检查此代码:

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

N = 1440
time = pd.date_range('2020-01-01', periods = N, freq = 'min')
globalpower = np.random.randn(N)
df = pd.DataFrame({'time': time,
                   'globalpower': globalpower})

graph = sns.lineplot(df.time, df.globalpower, data = df)
graph.xaxis.set_major_locator(mdates.HourLocator(interval = 1))
graph.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
plt.xticks(rotation = 90)

plt.show()

这给了我一个情节:

enter image description here

可以使用以下选项调整x轴标记和标签:

  • graph.xaxis.set_major_locator(mdates.HourLocator(interval = 1))设置每小时的滴答声
  • graph.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))将x轴标签的格式设置为“小时:分钟”
  • plt.xticks(rotation = 90)将x轴标签旋转90度以提高可视化效果

相关问题 更多 >