Posts: 279
Threads: 107
Joined: Aug 2019
Hopefully this isn't too hard to follow.
Fri_2017 is a list of the first 20 Fridays in 2017 as type datetime.datetime .
I also have this:
for i in range(20):
random_pnl_list.append(random.randint(-1000,1000))
cumul_pnl_from_random = list(np.cumsum(random_pnl_list)) Now... when I do this in matplotlib:
plt.plot(Fri_2017,cumul_pnl_from_random) I get x-axis labels at the first and 22nd of the first five months (e.g. 2017-01-01, 2017-01-22, 2017-02-01... 2017-05-01, 2017-05-22). How is this determined--both format and those two particular dates of every month?
I also have this line:
converted_Fri_2017 = [d.strftime('%Y-%m-%d') for d in Fri_2017] When I do:
plt.plot(converted_Fri_2017,cumul_pnl_from_random) I get x-axis labels of same format as above (yyyy-mm-dd) but every Friday from 1/6/17 through 5/19/17 (20 total labels). Why the difference?
Posts: 6,812
Threads: 20
Joined: Feb 2020
You should post your code so others can run it. I tried to duplicate from the description.
import random
import matplotlib.pyplot as plt
import numpy as np
from datetime import date, timedelta
def friday(year):
day = date(year, 1, 1)
day += timedelta(days=(4 - day.weekday())%7)
week = timedelta(weeks=1)
while day.year == year:
yield day
day += week
random_pnl_list = []
for i in range(20):
random_pnl_list.append(random.randint(-1000,1000))
cumul_pnl_from_random = list(np.cumsum(random_pnl_list))
fridays = list(friday(2017))[:len(cumul_pnl_from_random)]
plt.plot(fridays, cumul_pnl_from_random)
plt.show() My guess is matplotlib is doing the same kind of thing it does with numbers; picking nice start and stop values that it can divide into evenly sized intervals appropriate for the plot. When you convert the dates to strings they become just that, strings. Matplotlib does not know what they mean, does not know how they should be spaced, and just spaces them evenly without worrying about the "value" of the first or last x value.
Code for getting fridays in "%m-%d" format.
def friday(year):
day = date(year, 1, 1)
day += timedelta(days=(4 - day.weekday())%7)
week = timedelta(weeks=1)
while day.year == year:
yield day.strftime('%m-%d')
# yield day
day += week
Posts: 279
Threads: 107
Joined: Aug 2019
Mar-23-2022, 01:26 PM
(This post was last modified: Mar-23-2022, 03:13 PM by Yoriz.
Edit Reason: removed unnecessary quote of previous post
)
Done with the Fri_2017 list, x-axis labels are periodic but asymmetric as the 22nd and 1st are close together followed by a longer space and then another 22nd and 1st, etc. Is this "evenly sized intervals appropriate for the plot?" I would have thought if left to auto scale, matplotlib would have selected intervals that were really evenly spaced out (e.g. every Z x-value increments and since an x-value here is one week, that translates to every Z weeks).
Incidentally, last time I posted a question about matplotlib I didn't get a response and I figured that might have been because the code was too long and messy for people to bother wading through.
Sorry you had to take the time to reconstruct everything, Dean. My code here went something like this:
from datetime import datetime
from datetime import timedelta
import random
import numpy as np
import matplotlib.pyplot as plt
Fri_2017 = [] #2017_Fri gives "invalid decimal literal" at the underscore
random_pnl_list = []
cumul_pnl_from_random = []
start_date = datetime(2017,1,1) #not datetime.datetime()
while True: #True must be capitalized
if start_date.weekday() == 4:
Fri_2017.append(start_date)
break
else:
start_date += timedelta(days=1)
for i in range(19):
Fri_2017.append(Fri_2017[-1] + timedelta(days=7))
converted_Fri_2017 = [d.strftime('%Y-%m-%d') for d in Fri_2017] #list comprehension
print(converted_Fri_2017)
for i in range(20):
random_pnl_list.append(random.randint(-1000,1000))
cumul_pnl_from_random = list(np.cumsum(random_pnl_list)) #np returns array but this MUCH easier than doing loop to compute
print(random_pnl_list)
print(cumul_pnl_from_random)
fig, [ax1, ax2] = plt.subplots(2)
plt.sca(ax1)
plt.plot(Fri_2017,cumul_pnl_from_random)
plt.xticks(rotation=90)
plt.sca(ax2)
plt.plot(converted_Fri_2017,cumul_pnl_from_random)
plt.xticks(rotation=90)
plt.tight_layout()
plt.show()
Posts: 6,812
Threads: 20
Joined: Feb 2020
My version of your code labels the first and fifteenth of each month. Our Fridays must be different.
Posts: 279
Threads: 107
Joined: Aug 2019
(Mar-23-2022, 02:56 PM)deanhystad Wrote: My version of your code labels the first and fifteenth of each month. Our Fridays must be different.
That makes a lot more sense... 14 days apart followed by another 14-17 days is more evenly spaced than 21 days apart followed by another 8-10 days. Why might this be?
My list is the first 20 Fridays of 2017.
Posts: 6,812
Threads: 20
Joined: Feb 2020
Mine are dates, yours are datetimes. Strange that makes a difference.
Posts: 279
Threads: 107
Joined: Aug 2019
Mar-23-2022, 05:45 PM
(This post was last modified: Mar-23-2022, 05:45 PM by Mark17.)
(Mar-23-2022, 05:06 PM)deanhystad Wrote: Mine are dates, yours are datetimes. Strange that makes a difference.
I changed L1 of my code to "from datetime import date" and L11 to "start_date = date(2017,1,1)" The x-axis label output was the same (1st and 22nd of each month) while confirming that Fri_2017 is populated with <class 'datetime.date'> (it was previously <class 'datetime.datetime'>). Does this mean it's something other than date vs. datetime?
By the way, I found this related discussion: https://bit.ly/3tyZHRP One poster also found ticks to fall on 1st and 15th of every month as you did.
Posts: 6,812
Threads: 20
Joined: Feb 2020
Must be different versions of something. I run your code and get x ticks on 1 and 15 for the top plot (datetime) and weekly ticks on the bottom plot (strings).
Posts: 279
Threads: 107
Joined: Aug 2019
(Mar-23-2022, 05:58 PM)deanhystad Wrote: Must be different versions of something. I run your code and get x ticks on 1 and 15 for the top plot (datetime) and weekly ticks on the bottom plot (strings).
Thanks!
|