controlling the x ticks date values

12,781

Solution 1

Your problem is that your graph only has five ticks, so it can only display five labels. If you want to display all the labels, then you need to make sure that you have the same number of ticks.

I don't have pandas installed, and anyway, don't have the full data so can't re-create the labels. I have simply copied the list of labels you have provided. I have also 'reverse-engineered' the min & max for the x-axis from the labels (so that the data plots in the right place).

This line: ax.xaxis.set_ticks(np.arange(min_x, max_x, int((max_x-min_x)/len(labels)))) Ensures that you have the same number of ticks as labels.

Note that I have also changed the horizontal alignment of the labels so that, even when squashed up, it is still clear which tick the label corresponds to. This slice of the data appears to plot in the right location, so I'm pretty sure the labels are in the right place.

(Obviously the y-axis can be treated in the same way)

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

Solution 2

Limits of your x-axis data is only from 2012-12-05 06:12:06 to 2012-12-05 08:22:19. You have to expand date range.

However you may use this code to set x-axis ticks every 3 month:

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()

If I expand x-axis limits I get something like this on your data:

...
# 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

If you want more complicated datetime tick labels read this answer.

Share:
12,781

Related videos on Youtube

M.M
Author by

M.M

Updated on September 14, 2022

Comments

  • M.M
    M.M over 1 year

    I have the following data sample as x,y pairs and both x and y are Unix time-stamps:

    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
    

    and I want to plot it as scatter, but without the ugly time stamp format shown on x and y axis. Instead, I wanted to plot dates on the axis (in format YYYY-MM-DD or any other readable format) and show them with 3 months difference.

    I have the following code:

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

    where getLabels(s,t) is defined as:

    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
    

    and returns something like:

    ['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']
    

    Now, the problem is that the x axis ticks labels are not shown exactly as they are in the previous array of dates, instead, it shows only the first 6 dates (starting from 2012-09-30 and ending with 2013-12-31)

    what is the problem?

    • Alicia Garcia-Raboso
      Alicia Garcia-Raboso almost 8 years
      The first component of all the points you give correspond to the same day (2012-12-04), with little more than a two-hour difference between the first and last rows. If you're talking about a 3-month spread for the ticks, it'd be helpful if you gave a sample of data points with a wider spread. Also, please try to provide a Minimal, Complete, and Verifiable example (stackoverflow.com/help/mcve)