Home > Back-end >  How to set appropriate x-axis scale
How to set appropriate x-axis scale

Time:09-29

I wrote a function to plot 3 graphs from different dicts, however the dicts can change depending on which json file the user choose, so the code should be able to adjust the x axis scale somehow on its own (the x-axis is date).

But when I try to run the code I get something like this

current output

Here is my code to plot

def plot_averages(morning_dict , night_dict, hourly_dict):
    plt.plot(morning_dict.keys() , morning_dict.values() ,"r*",  label = "Daily mean")
    plt.plot(night_dict.keys() , night_dict.values() ,"b*",  label = "Night mean")
    plt.plot(hourly_dict.keys(), hourly_dict.values() , "g." ,   label = "Hourly value")
    plt.xlabel("Date")
    plt.ylabel("Value")
    plt.title(file_name)
    plt.legend()
    plt.show()

And those are the values plotted in figure above (sample since it's pretty long)

hourly_dict =
{'2022-05-12 06:00:00': 11.8,
 '2022-05-12 18:00:00': 12.5,
 '2022-05-13 06:00:00': 10.9,
 '2022-05-13 18:00:00': 13.5,
 '2022-05-14 06:00:00': 11.8,
 '2022-05-14 18:00:00': 15.1,
 '2022-05-15 06:00:00': 11.7,
 '2022-05-15 18:00:00': 13.2,
 '2022-05-16 06:00:00': 12.1,
 '2022-05-16 18:00:00': 10.2,
 '2022-05-17 06:00:00': 11.0,
 '2022-05-17 18:00:00': 10.0,
 '2022-05-18 06:00:00': 10.0,
 '2022-05-18 18:00:00': 16.6,
 '2022-05-19 06:00:00': 12.7,
 '2022-05-19 18:00:00': 21.3,
 '2022-05-20 06:00:00': 15.1,
 '2022-05-20 18:00:00': 11.6,
 '2022-05-21 06:00:00': 8.2,}
Morning_dict =
{'2022-06-01 06:00:00': 11.7,
 '2022-07-01 06:00:00': 21.6,
 '2022-08-01 06:00:00': 15.3,
 '2022-09-01 06:00:00': 11.3,
 '2022-06-02 06:00:00': 12.0,
 '2022-07-02 06:00:00': 17.2,
 '2022-08-02 06:00:00': 15.2,
 '2022-09-02 06:00:00': 12.1,
 '2022-06-03 06:00:00': 13.6,
 '2022-07-03 06:00:00': 18.5,
 '2022-08-03 06:00:00': 18.9,
 '2022-09-03 06:00:00': 9.2,
 '2022-06-04 06:00:00': 13.7,
 '2022-07-04 06:00:00': 16.5,
 '2022-08-04 06:00:00': 21.6,
 '2022-09-04 06:00:00': 13.5,
 '2022-06-05 06:00:00': 17.0,
 '2022-07-05 06:00:00': 16.3,
 '2022-08-05 06:00:00': 19.7,
 '2022-09-05 06:00:00': 8.7,
 '2022-06-06 06:00:00': 16.2,
 '2022-07-06 06:00:00': 15.6,
 '2022-08-06 06:00:00': 14.3,
 '2022-09-06 06:00:00': 5.9,
 '2022-06-07 06:00:00': 15.1,
 '2022-07-07 06:00:00': 14.9,
 '2022-08-07 06:00:00': 14.4,
 '2022-09-07 06:00:00': 8.9,
 '2022-06-08 06:00:00': 16.1,
 '2022-07-08 06:00:00': 14.1,
 '2022-08-08 06:00:00': 15.9,}
Night_dict =
{'2022-06-01 18:00:00': 13.9,
 '2022-07-01 18:00:00': 23.9,
 '2022-08-01 18:00:00': 22.0,
 '2022-09-01 18:00:00': 12.3,
 '2022-06-02 18:00:00': 15.6,
 '2022-07-02 18:00:00': 21.8,
 '2022-08-02 18:00:00': 21.9,
 '2022-09-02 18:00:00': 11.3,
 '2022-06-03 18:00:00': 15.2,
 '2022-07-03 18:00:00': 21.9,
 '2022-08-03 18:00:00': 26.1,
 '2022-06-04 18:00:00': 18.2,
 '2022-07-04 18:00:00': 20.9,
 '2022-08-04 18:00:00': 27.0,
 '2022-06-05 18:00:00': 22.9,
 '2022-07-05 18:00:00': 19.7,}

Since you can see the hourly_dict is split into 2 dicts, morning and night, and therefore it should be showing twice as much points in the graph, but there are somehow equally number of points for all of them overlapping. I guess the problem is the x-axis scale. How can I fix that?

CodePudding user response:

There are two things you will need to do. First, convert the dates in the 3 dictionaries to datetime format. This will allow matplotlib to set the dates in the correct order as well as let you format the axis.

Then, once you plot, you can use set_major_formatter and set_major_locator to adjust how many ticks you want. Optionally, you can also use autofmt_xdate() to let matplot adjust/rotate the labels as needed. Please see the below code. I have used the ticks for one in 14 days. You can change it to higher/lower number or even do a month format (check out the commented code). Hope this is what you are looking for.

## Assuming you already have the 3 dictionaries above
from datetime import datetime
## Convert each dictionary value to datetime
hourly_dict = {datetime.strptime(key, "%Y-%m-%d %H:%M:%S"): val for key, val in hourly_dict.items()}
morning_dict = {datetime.strptime(key, "%Y-%m-%d %H:%M:%S"): val for key, val in morning_dict.items()}
night_dict = {datetime.strptime(key, "%Y-%m-%d %H:%M:%S"): val for key, val in night_dict.items()}

##Plot graph - no change here
plt.plot(morning_dict.keys() , morning_dict.values() ,"r*",  label = "Daily mean")
plt.plot(night_dict.keys() , night_dict.values() ,"b*",  label = "Night mean")
plt.plot(hourly_dict.keys(), hourly_dict.values() , "g." ,   label = "Hourly value")
plt.xlabel("Date")
plt.ylabel("Value")
plt.title('file_name')

## Tell how many days gap should be between each tick (14 days here) - month in comment
import matplotlib.dates as mdates
plt.gca().xaxis.set_major_locator(mdates.DayLocator(interval=14))   #to get a tick every 14 days
#plt.gca().xaxis.set_major_locator(mdates.MonthLocator(interval=1))   #to get a tick once a month

#How should the tick labels appear - DD-MM-YYY here
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%d-%m-%Y'))     #How the date format looks
plt.gcf().autofmt_xdate()  ##Let matplotlib autoformat x-dates
plt.legend()
plt.show()

enter image description here

  • Related