![]() |
x-axis labels with Matplotlib - Printable Version +- Python Forum (https://python-forum.io) +-- Forum: Python Coding (https://python-forum.io/forum-7.html) +--- Forum: General Coding Help (https://python-forum.io/forum-8.html) +--- Thread: x-axis labels with Matplotlib (/thread-36721.html) |
x-axis labels with Matplotlib - Mark17 - Mar-22-2022 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? RE: x-axis labels with Matplotlib - deanhystad - Mar-22-2022 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 RE: x-axis labels with Matplotlib - Mark17 - Mar-23-2022 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() RE: x-axis labels with Matplotlib - deanhystad - Mar-23-2022 My version of your code labels the first and fifteenth of each month. Our Fridays must be different. RE: x-axis labels with Matplotlib - Mark17 - Mar-23-2022 (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. RE: x-axis labels with Matplotlib - deanhystad - Mar-23-2022 Mine are dates, yours are datetimes. Strange that makes a difference. RE: x-axis labels with Matplotlib - Mark17 - Mar-23-2022 (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. RE: x-axis labels with Matplotlib - deanhystad - Mar-23-2022 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). RE: x-axis labels with Matplotlib - Mark17 - Mar-23-2022 (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! |