控制x刻度日期值

2024-05-12 21:35:10 发布

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

下面的数据示例是x,y对,x和y都是Unix时间戳:

1354648326,1354648326
1354649456,1371775551
1354649664,1429649819
1354649667,1429644021
1354649683,1356976159
1354649767,1441369794
1354649863,1414467362
1354650486,1366297316
1354650757,1456962664
1354650789,1359398128
1354651552,1354656458
1354651555,1368631443
1354651591,1456420412
1354651616,1354651616
1354651715,1444573208
1354652048,1454443352
1354652382,1394722546
1354652687,1355993864
1354653448,1387378662
1354653731,1396094300
1354653769,1417765024
1354654110,1457230519
1354654111,1452854788
1354654179,1423877890
1354654266,1355148505
1354654374,1446848232
1354654374,1456864004
1354654615,1355858928
1354654700,1456945892
1354654707,1456265183
1354654744,1442939141
1354654747,1388436654
1354654771,1449799848
1354654775,1355177773
1354654808,1456857861
1354654809,1411369798
1354654855,1355934384
1354654915,1457100468
1354654962,1388784204
1354655085,1454446403
1354655219,1364196550
1354655232,1387214819
1354655262,1377170885
1354655264,1369689630
1354655289,1388750388
1354655389,1387387305
1354655434,1389255185
1354655436,1387165968
1354655592,1374369153
1354655661,1456912753
1354655811,1354718201
1354655889,1426675579
1354656139,1420486774

我想把它绘制成散点图,但是没有在x轴和y轴上显示的丑陋的时间戳格式。 相反,我想在轴上绘制日期(格式为YYYY-MM-DD或任何其他可读格式),并用3个月的时间差来显示它们。

我有以下代码:

ax.set_xticklabels(getLabels(s,t),rotation=20)

其中getLabels(s,t)定义为:

def getLabels(s,t): #s and t are unix time stamps
    labels =[]
    for x in pd.date_range(start=s, end=t, freq='3M'):
        labels.append(str(x).replace(" 00:00:00",""))
    print labels
    return labels

返回如下内容:

['2012-06-30', '2012-09-30', '2012-12-31', '2013-03-31', '2013-06-30', '2013-09-30', '2013-12-31', '2014-03-31', '2014-06-30', '2014-09-30', '2014-12-31', '2015-03-31', '2015-06-30', '2015-09-30', '2015-12-31', '2016-03-31']
['2012-06-30', '2012-09-30', '2012-12-31', '2013-03-31', '2013-06-30', '2013-09-30', '2013-12-31', '2014-03-31', '2014-06-30', '2014-09-30', '2014-12-31', '2015-03-31', '2015-06-30', '2015-09-30', '2015-12-31', '2016-03-31']

现在,问题是x轴刻度标签显示的日期与前一个日期数组中的日期不完全相同,而是只显示前6个日期(从2012-09-30开始,到2013-12-31结束)

怎么了?


Tags: 数据代码示例labels格式时间绘制unix
2条回答

问题是图形只有五个刻度,因此只能显示五个标签。如果要显示所有标签,则需要确保刻度数相同。

我没有安装pandas,也没有完整的数据,所以无法重新创建标签。我只是复制了你提供的标签清单。我还从标签中“逆向设计”了x轴的最小值和最大值(以便数据绘制在正确的位置)。

这一行:ax.xaxis.set_ticks(np.arange(min_x, max_x, int((max_x-min_x)/len(labels)))) 确保刻度数与标签数相同。

请注意,我还更改了标签的水平对齐方式,以便即使压扁了标签,也仍然可以清楚地看到标签对应的刻度。这段数据似乎是在正确的位置绘制的,所以我很确定标签是在正确的位置。

(显然y轴可以用同样的方法处理)

import matplotlib.pyplot as plt
import numpy as np
import time
import datetime

labels =['2012-06-30', '2012-09-30', '2012-12-31', '2013-03-31',
         '2013-06-30', '2013-09-30', '2013-12-31', '2014-03-31',
         '2014-06-30', '2014-09-30', '2014-12-31', '2015-03-31',
         '2015-06-30', '2015-09-30', '2015-12-31', '2016-03-31']
x = []
y = []
with open('data.txt','r') as myfile:
    for line in myfile:
        _x, _y = line.strip().split(',')
        x.append(int(_x))
        y.append(int(_y))

min_x = int(time.mktime(datetime.datetime.strptime('2012-06-30','%Y-%m-%d').timetuple()))
max_x = int(time.mktime(datetime.datetime.strptime('2016-03-31','%Y-%m-%d').timetuple()))

print (datetime.datetime.fromtimestamp(min(x)).strftime('%Y-%m-%d')) 
# Confirm that we are plotting in the right place for this sample

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
ax.set_xlim(min_x, max_x)
ax.xaxis.set_ticks(np.arange(min_x, max_x, int((max_x-min_x)/len(labels))))
ax.set_xticklabels(labels, rotation=20, horizontalalignment = 'right')
ax.scatter(x,y)
plt.show()

enter image description here

x轴数据的限制仅从2012-12-05 06:12:062012-12-05 08:22:19。你必须扩大日期范围。

但是,您可以使用此代码每3个月设置一次x轴刻度:

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

def grouped(iterable, n):
    return izip(*[iter(iterable)]*n)

def getLabels(s,t):
    labels =[]
    for x in pd.date_range(start=s, end=t, freq='3M'):
        labels.append(x.strftime("%Y-%m-%d"))
    print labels
    return labels

arr = [1354648326,1354648326,
1354649456,1371775551,
...
1354655889,1426675579,
1354656139,1420486774]

# convert timestamps to datetime objects
X = list()
Y = list()
for x, y in grouped(arr, 2):
    X.append(datetime.datetime.fromtimestamp(x))
    Y.append(datetime.datetime.fromtimestamp(y))

# range of X list is only one day: 2012-12-05
# you have to enlarge data of X
print np.min(X),np.max(X)

# sample data
data = np.random.uniform(-10, 10, size=len(X)*len(Y))

# plot
plt.scatter(X, Y, s = data)
ax = plt.gca()
# set limits for X-axis
ax.set_xlim([np.min(X),np.max(X)])
# generate labels
xlabels = getLabels(np.min(X),np.max(X))
# set ticks and labels
ax.set_xticks(xlabels)
ax.set_xticklabels(xlabels,rotation=20)

plt.show()

如果我扩展x轴限制,我会在您的数据上得到类似的结果:

...
# plot
plt.scatter(X, Y, s = data)
ax = plt.gca()
# set limits for X-axis
xmin = datetime.datetime(2012,1,1,0,0,0) # np.min(X)
xmax = xmin + datetime.timedelta(days = 360) # np.max(X)
ax.set_xlim([xmin, xmax])
# generate labels every 3 month
xlabels = getLabels(xmin, xmax)
# set ticks and labels
ax.set_xticks(xlabels)
ax.set_xticklabels(xlabels,rotation=20)
plt.show()

enter image description here

如果您想要更复杂的日期时间刻度标签,请阅读answer

相关问题 更多 >