Posts: 203
Threads: 41
Joined: Mar 2019
Jun-06-2019, 09:00 PM
(This post was last modified: Jun-07-2019, 12:42 PM by mcgrim.)
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()
Posts: 203
Threads: 41
Joined: Mar 2019
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.
Posts: 606
Threads: 3
Joined: Nov 2016
Jun-07-2019, 01:36 PM
(This post was last modified: Jun-07-2019, 01:37 PM by heiner55.)
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
Posts: 95
Threads: 3
Joined: May 2019
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. For example, I'm not sure why the position3 is used in mov_index instead of last row position. position3 is the position of the first "2015-05-14" date. This means that when range(position1, position3, 30) is used then it ignores all the lines between the first "2015-05-14" and the end of the file (the same applies to all values before the "2015-05-12"). Is that desired behaviour?
Posts: 2,168
Threads: 35
Joined: Sep 2016
(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()
Posts: 203
Threads: 41
Joined: Mar 2019
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?
|