Python Forum
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
xticks
#1
I am trying to put in a bar graph some values stored in a file and the times when these values took place.
The bar chart looks like the way I want as long as I have it without dates, but once I introduce plt.xticks(date_list) in the second last line of my code, the graph turns blank.
How do I fix this?
Also, how would be possible to introduce a second xticks to divide this axis into hours as well?

I would like to ask you that in case I am not being clear or more info is needed or whatever issue you may have with my line of questioning, let me please know what in my thread should be fixed.


I included an attached file containing the data I am working with.

I would only need you to refer to the last part of the code dealing with graphing, even though I am posting the whole code here, which is needed in order to run it properly.

import numpy as np

import matplotlib.pyplot as plt
import datetime

import pytz
                
dt_fmt = '%Y-%m-%d %H:%M:%S.%f'

orig_date=[]
orig_time=[]
movements=[]

with open('moredates.txt', 'r') as f:
    for line in f:
        data = line.split()    # Splits on whitespace        
        orig_date.append(data[0][:])
        orig_time.append((data[1][:]))
        movements.append(int(data[2][:]))
timestamps = []

for col_dt in zip(orig_date , orig_time):
    
    new_dt_str = ' '.join(col_dt)
    new_dt = datetime.datetime.strptime(new_dt_str, dt_fmt)
    timestamps.append(new_dt)
    

def convert_local_timezone():
    """ conversion from strings to datetime objects"""
    converted_dates=[]
    for date in timestamps:
        local_tz = pytz.timezone('Europe/Copenhagen')
        local_time = date.replace(tzinfo=pytz.utc).astimezone(local_tz)
        converted_dates.append(local_time)
    return converted_dates

CEU_times=convert_local_timezone()


def mov_index(i,j):
    a=[movements[i] - movements[i-1] for i in range(i,j,30)]  # function calculating
    return a                                                  # the values                          

position1 =  orig_date.index(('2015-05-12'))
position2 = orig_date.index('2015-05-13')
position3 = orig_date.index('2015-05-14')


start_date = CEU_times[position1].date()

y=[mov_index(position1,position3)][0][:]



date_list = [start_date + datetime.timedelta(days=x) for x in range(0, 3)] 


plt.bar(np.arange(len(y[0:-1])),y[0:-1], width=1, color='blue' )

plt.xticks(date_list)  # if this line is removed, the graph looks ok

plt.show()

Attached Files

.txt   moredates.txt (Size: 75.2 KB / Downloads: 7)
Reply
#2
all I need is to know what is wrong with line 71.
I am noticing that plenty of you visited my thread but I haven't got a single answer.
Let me please know if this code is easy to run for you or if it should be changed.
Let me please know if there is anything wrong with the way I presented the question.
Reply
#3
There is no line 71.

date_list is a list with 3 values.
Change line 61 to:

plt.xticks((0, 20, 40), date_list)
See also:
https://matplotlib.org/3.1.0/api/_as_gen...ticks.html
Reply
#4
Hi, if you take a look at the documentation of xticks it allows you to pass additional "labels" argument.

from scipy import *
from pylab import*
import numpy as np
from numpy import array
import matplotlib.pyplot as plt
import datetime
from datetime import timezone
from datetime import timedelta
import matplotlib.dates as dates
import pandas as pd  
import pytz
import matplotlib.dates as mdates
import sys
from matplotlib.dates import (YEARLY, DateFormatter,
                              rrulewrapper, RRuleLocator, drange)
 
                 
dt_fmt = '%Y-%m-%d %H:%M:%S.%f'
 
orig_date=[]
orig_time=[]
movements=[]
 
with open('moredates.txt', 'r') as f:
    for line in f:
        data = line.split()    # Splits on whitespace        
        orig_date.append(data[0])
        orig_time.append((data[1]))
        movements.append(int(data[2]))
        
timestamps = []
 
for col_dt in zip(orig_date , orig_time):
     
    new_dt_str = ' '.join(col_dt)
    new_dt = datetime.datetime.strptime(new_dt_str, dt_fmt)
    timestamps.append(new_dt)
     
 
def convert_local_timezone():
    """ conversion from strings to datetime objects"""
    converted_dates=[]
    for date in timestamps:
        local_tz = pytz.timezone('Europe/Copenhagen')
        local_time = date.replace(tzinfo=pytz.utc).astimezone(local_tz)
        converted_dates.append(local_time)
    return converted_dates
 
CEU_times=convert_local_timezone()

MAGIC_NUMBER = 30

def mov_index(min_, max_):
    a=[movements[i] - movements[i-1] for i in range(min_, max_, MAGIC_NUMBER)]  # function calculating
    return a                                                  # the values                          


#start_date = CEU_times[position1].date()

og = np.array(orig_date)
pos = np.where(og[1:] != og[:-1])[0] + 1 # find where dates change in the array
pos = np.insert(pos, 0, 0)         # prepend 1st date position

date_list = og.take(pos)

y = mov_index(pos[1], pos[-1])
 
plt.bar(np.arange(len(y[0:-1])),y[0:-1], width=1, color='blue' )

plt.xticks(pos // MAGIC_NUMBER, date_list)  # if this line is removed, the graph looks ok

plt.show()
It seems to work but it's hard to help without knowing the goal you're trying to accomplish with the code. That's because of the uncertainty whether some part of the code is a bug or feature.
Reply
#5
(Jun-06-2019, 09:00 PM)mcgrim Wrote: I would only need you to refer to the last part of the code dealing with graphing, even though I am posting the whole code here, which is needed in order to run it properly.

I'll give you an idea of how to remove all the irrelevant code from the problem at hand.

date_list = [start_date + datetime.timedelta(days=x) for x in range(0, 3)]
is used in the plot
if you print(date_list) it returns 3 datetime.date's
Output:
[datetime.date(2015, 5, 12), datetime.date(2015, 5, 13), datetime.date(2015, 5, 14)]
this can be replace with
from datetime import date

date_list = [date(2015, 5, 12), date(2015, 5, 13), date(2015, 5, 14)]

now the data in plt.bar(np.arange(len(y[0:-1])), y[0:-1], width=1, color='blue')
print(list(np.arange(len(y[0:-1]))))
Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46]
this can be replaced with
data1 = range(47)

print(y[0:-1])
Output:
[0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 1, 2, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 10, 2, 0, 1, 0, 1, 0, 2, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0]
this can be replaced with
data2 = [0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 1, 2, 4, 4, 0, 0, 0,
         0, 0, 0, 0, 0, 10, 2, 0, 1, 0, 1, 0, 2, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0]


All your code can be reduced to the following
import matplotlib.pyplot as plt
from datetime import date

date_list = [date(2015, 5, 12), date(2015, 5, 13), date(2015, 5, 14)]
data1 = range(47)
data2 = [0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 1, 2, 4, 4, 0, 0, 0,
         0, 0, 0, 0, 0, 10, 2, 0, 1, 0, 1, 0, 2, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0]

plt.bar(data1,data2, width=1, color='blue' )

# plt.xticks(date_list) # if this line is removed, the graph looks ok

plt.show()
with the commented out line being the issue that the dates are not showing and messed up the graph

If you look up
https://matplotlib.org/3.1.0/api/_as_gen...lot-xticks Wrote:matplotlib.pyplot.xticks(ticks=None, labels=None, **kwargs)[source]
Get or set the current tick locations and labels of the x-axis.

Call signatures:

locs, labels = xticks() # Get locations and labels
xticks(ticks, [labels], **kwargs) # Set locations and labels
Copy to clipboard
Parameters:
ticks : array_like
A list of positions at which ticks should be placed. You can pass an empty list to disable xticks.

labels : array_like, optional
A list of explicit labels to place at the given locs.

**kwargs
Text properties can be used to control the appearance of the labels.

Returns:
locs
An array of label locations.

labels
A list of Text objects.

Adding a list of positions for the ticks parameter makes everything show up
import matplotlib.pyplot as plt
from datetime import date

date_list = [date(2015, 5, 12), date(2015, 5, 13), date(2015, 5, 14)]
data1 = range(47)
data2 = [0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 6, 1, 0, 1, 2, 4, 4, 0, 0, 0,
         0, 0, 0, 0, 0, 10, 2, 0, 1, 0, 1, 0, 2, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0]

plt.bar(data1, data2, width=1, color='blue')

plt.xticks((0, 23, 46), date_list)

plt.show()
Reply
#6
I am now working with the same graph, but I would like to get the hours (every 3) between those dates,
but once I write this lines


time_list=[CEU_times[position1].hour() + datetime.timedelta(hours=i) for i in range(0,len(y),3)]
plt.bar(np.arange(len(y[0:-1])),y[0:-1], width=1, color='blue' )

plt.xticks((range(len(y))),(time_list), rotation=90)
gca().xaxis.tick_bottom()
plt.show()
I get the following error:
Error:
runfile('C:/Users/Desktop/python ode/dtnew.py', wdir='C:/Users/Desktop/python ode') Traceback (most recent call last): File "<ipython-input-676-1b5fe841af55>", line 1, in <module> runfile('C:/Users/Desktop/python ode/dtnew.py', wdir='C:/Users/Desktop/python ode') File "C:\Users\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 668, in runfile execfile(filename, namespace) File "C:\Users\Anaconda3\lib\site-packages\spyder_kernels\customize\spydercustomize.py", line 108, in execfile exec(compile(f.read(), filename, 'exec'), namespace) File "C:/UsersDesktop/python ode/dtnew.py", line 73, in <module> time_list=[CEU_times[position1].hour() + datetime.timedelta(hours=i) for i in range(0,len(y))] File "C:/Users/Desktop/python ode/dtnew.py", line 73, in <listcomp> time_list=[CEU_times[position1].hour() + datetime.timedelta(hours=i) for i in range(0,len(y))] TypeError: 'int' object is not callable
any idea on why the error and how to fix it?
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  tell exact difference between xlim() and xticks() function ift38375 3 5,251 Jul-12-2019, 12:04 AM
Last Post: scidam

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020