Pretty new to python and programming in general so bear with me please. I have a data set imported from a .csv file and I'm trying to plot a column of values (y axis) by date (x axis) over a 1 year period but the problem is that the dates are way too dense and I can't for the life of me figure out how to space them out or modify how they're defined. Here's the code I'm working with:
import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib as mpl
from scipy import stats
import cartopy.crs as ccrs
import cartopy.io.img_tiles as cimgt
df = pd.read_csv('Vanuatu Earthquakes 2018-2019.csv')
and here's the line plot code:
plt.figure(figsize=(15, 7))
ax = sns.lineplot(x='date', y='mag', data=df).set_title("Earthquake magnitude May 2018-2019")
plt.xlabel('Date')
plt.ylabel('Magnitude (Mw)')
plt.savefig('EQ mag time')
This currently gives me this line plot:
Currently I want to do it by something like a small tick for each day and a larger tick + label for the beginning of each week. Doesn't have to be exactly that but I'm mostly looking to just decrease the density. I've looked at loads of posts on here but none of them seem to work for my situation so any help would be greatly appreciated.
[Update]
Got the dates working as per Konqui's advice below and my code now looks like this:
time = pd.date_range(start = '01-05-2018',
end = '01-05-2019',
freq = 'D')
df = pd.DataFrame({'date': list(map(lambda x: str(x), time)),
'mag': np.random.random(len(time))})
plt.figure(figsize=(15, 7))
df['date'] = pd.to_datetime(df['date'], format = '%Y-%m')
ax = sns.lineplot(x='date', y='mag', data=df).set_title("Earthquake magnitude May 2018-2019")
ax.xaxis.set_major_locator(md.WeekdayLocator(byweekday = 1))
ax.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d'))
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)
ax.xaxis.set_minor_locator(md.DayLocator(interval = 1))
plt.xlabel('Date')
plt.ylabel('Magnitude (Mw)')
which gives me an error message: AttributeError: 'Text' object has no attribute 'xaxis'
. Any thoughts?
To decrease the density of x-ticks in Seaborn, we can use set_visible=False for odd positions.
plt. plot(x, y) plt.
I suppose you start from a dataframe similar to this one saved in a Vanuatu Earthquakes 2018-2019.csv
file :
import pandas as pd
import numpy as np
time = pd.date_range(start = '01-01-2020',
end = '31-03-2020',
freq = 'D')
df = pd.DataFrame({'date': list(map(lambda x: str(x), time)),
'mag': np.random.random(len(time))})
output:
date mag
0 2020-01-01 00:00:00 0.940040
1 2020-01-02 00:00:00 0.765570
2 2020-01-03 00:00:00 0.951839
3 2020-01-04 00:00:00 0.708172
4 2020-01-05 00:00:00 0.705032
5 2020-01-06 00:00:00 0.857500
6 2020-01-07 00:00:00 0.866418
7 2020-01-08 00:00:00 0.363287
8 2020-01-09 00:00:00 0.289615
9 2020-01-10 00:00:00 0.741499
plotting:
import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize = (15, 7))
sns.lineplot(ax = ax, x='date', y='mag', data=df).set_title('Earthquake magnitude May 2018-2019')
plt.xlabel('Date')
plt.ylabel('Magnitude (Mw)')
plt.show()
You should do a series of things:
First of all, you get that density of labels because your 'date'
values are str
type, you need to convert them to datetime
by
df['date'] = pd.to_datetime(df['date'], format = '%Y-%m-%d')
in this way your x axis is a datetime
type and the above plot will become this:
Then you have to adjust ticks; for the major ticks you should set:
import matplotlib.dates as md
# specify the position of the major ticks at the beginning of the week
ax.xaxis.set_major_locator(md.WeekdayLocator(byweekday = 1))
# specify the format of the labels as 'year-month-day'
ax.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d'))
# (optional) rotate by 90° the labels in order to improve their spacing
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)
and for the minor ticks:
# specify the position of the minor ticks at each day
ax.xaxis.set_minor_locator(md.DayLocator(interval = 1))
optionally, you can edit the length of the ticks with:
ax.tick_params(axis = 'x', which = 'major', length = 10)
ax.tick_params(axis = 'x', which = 'minor', length = 5)
so the final plot will become:
# import required packages
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import matplotlib.dates as md
# read the dataframe
df = pd.read_csv('Vanuatu Earthquakes 2018-2019.csv')
# convert 'date' column type from str to datetime
df['date'] = pd.to_datetime(df['date'], format = '%Y-%m-%d')
# prepare the figure
fig, ax = plt.subplots(figsize = (15, 7))
# set up the plot
sns.lineplot(ax = ax, x='date', y='mag', data=df).set_title('Earthquake magnitude May 2018-2019')
# specify the position of the major ticks at the beginning of the week
ax.xaxis.set_major_locator(md.WeekdayLocator(byweekday = 1))
# specify the format of the labels as 'year-month-day'
ax.xaxis.set_major_formatter(md.DateFormatter('%Y-%m-%d'))
# (optional) rotate by 90° the labels in order to improve their spacing
plt.setp(ax.xaxis.get_majorticklabels(), rotation = 90)
# specify the position of the minor ticks at each day
ax.xaxis.set_minor_locator(md.DayLocator(interval = 1))
# set ticks length
ax.tick_params(axis = 'x', which = 'major', length = 10)
ax.tick_params(axis = 'x', which = 'minor', length = 5)
# set axes labels
plt.xlabel('Date')
plt.ylabel('Magnitude (Mw)')
# show the plot
plt.show()
If you pay attention to the y axis in my plots, you see that 'mag'
values fall in the range (0-1)
. This is due to the fact that I generate this fake data with 'mag': np.random.random(len(time))
. If you read your data from the file Vanuatu Earthquakes 2018-2019.csv
, you will get the correct values on the y axis. Try to simply copy the code in the Complete code section.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With