我无法将我在 Seaborn 中的线图的 xticks 设置为相应小时的值
I am unable to set the xticks of my lineplot in Seaborn to the values of the coresponding hour
我尝试了很多不同的方法,但我无法获得合理的 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' ])
我知道应该有一种更优雅的方式来列出当天的时报。
输出如下所示:
我打印了我的数据头部,它看起来像这样:
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
由于我无权访问您的数据,因此我创建了一个假数据以便使用一些数据。您可以只使用 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()
这给了我这个情节:
您可以通过以下方式调整 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 度以改善可视化效果
只有一点点要添加到 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]
请注意,我每次重复 3 次,以便 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'])
基本的差异是您的绘图函数和 x 轴参数都不知道有任何时间信息。当您使用 x=df.time
和 y=df.globalpower
调用 sns.lineplot
时,seaborn
基本上对每个唯一条目的时间列执行 groupby 操作,并对全局功率值进行平均。 但它只在时间列中看到独特的字符串,这些独特的字符串在绘制时被排序,由于它们是按字母数字书写的方式,这恰好与一天中的时间顺序相匹配。
要看到这一点,请考虑使用 非时间格式字符串数组 (例如“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'])
所以当你谈到你的刻度参数时,说 set_xticks(range(0,24))
和 set_xticklabels(['01:00','02:00','03:00'...])
基本上意味着“用这 24 个标签在位置 0 到 23 设置刻度”,尽管情节是图形化的(在这个case) 1440 个唯一的 x 值,因此 0-23 仅跨越一小部分值。
修复基本上就是 Andrea 回答的问题:将您的时间信息转换为 datetime
格式,然后使用 matplotlib.dates
格式化刻度。对于你的时间字符串(没有日期),你可以简单地做:
df['time'] = pd.to_datetime(df['time'])
然后按照他们的回答。这将在 1970 年 1 月 1 日每次给出一个完整的时间戳(pandas
中的默认值);但如果您只关心绘制每个重复时间的平均 24 小时周期,那么奇怪的年份并不重要。
我尝试了很多不同的方法,但我无法获得合理的 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' ])
我知道应该有一种更优雅的方式来列出当天的时报。
输出如下所示:
我打印了我的数据头部,它看起来像这样:
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
由于我无权访问您的数据,因此我创建了一个假数据以便使用一些数据。您可以只使用 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()
这给了我这个情节:
您可以通过以下方式调整 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 度以改善可视化效果
只有一点点要添加到 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]
请注意,我每次重复 3 次,以便 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'])
基本的差异是您的绘图函数和 x 轴参数都不知道有任何时间信息。当您使用 x=df.time
和 y=df.globalpower
调用 sns.lineplot
时,seaborn
基本上对每个唯一条目的时间列执行 groupby 操作,并对全局功率值进行平均。 但它只在时间列中看到独特的字符串,这些独特的字符串在绘制时被排序,由于它们是按字母数字书写的方式,这恰好与一天中的时间顺序相匹配。
要看到这一点,请考虑使用 非时间格式字符串数组 (例如“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'])
所以当你谈到你的刻度参数时,说 set_xticks(range(0,24))
和 set_xticklabels(['01:00','02:00','03:00'...])
基本上意味着“用这 24 个标签在位置 0 到 23 设置刻度”,尽管情节是图形化的(在这个case) 1440 个唯一的 x 值,因此 0-23 仅跨越一小部分值。
修复基本上就是 Andrea 回答的问题:将您的时间信息转换为 datetime
格式,然后使用 matplotlib.dates
格式化刻度。对于你的时间字符串(没有日期),你可以简单地做:
df['time'] = pd.to_datetime(df['time'])
然后按照他们的回答。这将在 1970 年 1 月 1 日每次给出一个完整的时间戳(pandas
中的默认值);但如果您只关心绘制每个重复时间的平均 24 小时周期,那么奇怪的年份并不重要。