Matplotlib Plot time series with different periodicity - python
I have 2 dfs. One of them has data for a month. Another one, averages for the past quarters. I wanna plot the averages in front of the monthly data. How can I do it? Please note that I am trying to plot averages as dots and monthly as line chart.
So far my best result was achieved by ax1=ax.twiny(), but still not ideal result as data point appear in throughout the chart, rather than just in front.
import pandas as pd
import numpy as np
import matplotlib.dates as mdates
from matplotlib.ticker import ScalarFormatter, FormatStrFormatter, FuncFormatter
import matplotlib.ticker as ticker
import matplotlib.pyplot as plt
date_base = pd.date_range(start='1/1/2018', end='1/30/2018')
df_base = pd.DataFrame(np.random.randn(30,4), columns=list("ABCD"), index=date_base)
date_ext = pd.date_range(start='1/1/2017', end='1/1/2018', freq="Q")
df_ext = pd.DataFrame(np.random.randn(4,4), columns=list("ABCD"), index=date_ext)
def drawChartsPlt(df_base, df_ext):
fig = plt.figure(figsize=(10,5))
ax = fig.add_subplot(111)
number_of_plots = len(df_base.columns)
LINE_STYLES = ['-', '--', '-.', 'dotted']
colormap = plt.cm.nipy_spectral
ax.set_prop_cycle("color", [colormap(i) for i in np.linspace(0,1,number_of_plots)])
date_base = df_base.index
date_base = [i.strftime("%Y-%m-%d") for i in date_base]
q_ends = df_ext.index
q_ends = [i.strftime("%Y-%m-%d") for i in q_ends]
date_base.insert(0, "") #to shift xticks so they match chart
date_base += q_ends
for i in range(number_of_plots):
df_base.ix[:-3, df_base.columns[i]].plot(kind="line", linestyle=LINE_STYLES[i%2], subplots=False, ax=ax)
#ax.set_xticks(date_base)
#ax.set_xticklabels(date_base)
# ax.xaxis.set_major_locator(ticker.MultipleLocator(20))
ax.xaxis.set_major_locator(ticker.LinearLocator(len(date_base)))
ax.xaxis.set_major_formatter(plt.FixedFormatter(date_base))
fig.autofmt_xdate()
# ax1=ax.twinx()
ax1=ax.twiny()
ax1.set_prop_cycle("color", [colormap(i) for i in np.linspace(0,1,number_of_plots)])
for i in range(len(df_ext.columns)):
ax1.scatter(x=df_ext.index, y=df_ext[df_ext.columns[i]])
ax.set_title("Test")
#plt.minorticks_off())
ax.minorticks_off()
#ax1.minorticks_off()
#ax1.set_xticklabels(date_base)
#ax1.set_xticklabels(q_ends)
ax.legend(loc="center left", bbox_to_anchor=(1,0.5))
ax.xaxis.label.set_size(12)
plt.xlabel("TEST X Label")
plt.ylabel("TEST Y Label")
ax1.set_xlabel("Quarters")
plt.show()
drawChartsPlt(df_base, df_ext)
The way I ended up coding it is by saving quarterly index of df_ext to a temp variable, overwriting it with dates that are close to df_base.index using pd.date_range(start=df_base.index[-1], periods=len(df_ext), freq='D'), and the finally setting the dates that I need with ax.set_xticklabels(list(date_base)+list(date_ext)).
It looks like it could be achieved using broken axes as indicated Break // in x axis of matplotlib and Python/Matplotlib - Is there a way to make a discontinuous axis?, but I haven't tried that solution.
Related
How to add multiple custom ticks to seaborn boxplot
I generated a boxplot using seaborn. On the x axis, I would like to have, both the number of days (20, 25, 32) and the actual dates they refer to (2022-05-08, 2022-05-13, 2022-05-20). I found a potential solution at the following link add custom tick with matplotlib. I'm trying to adapt it to my problem but I could only get the number of days or the dates, not both. I really would appreciate any help. Thank you in advance for your time. Please, find below my code and the desired output. import pandas as pd import matplotlib.pyplot as plt import seaborn as sns df = pd.DataFrame({'nb_days':[20,20,20,25,25,20,32,32,25,32,32], 'Dates':['2022-05-08','2022-05-08','2022-05-08','2022-05-13','2022-05-13','2022-05-08','2022-05-20','2022-05-20','2022-05-13','2022-05-20','2022-05-20'], 'score':[3,3.5,3.4,2,2.2,3,5,5.2,4,4.3,5]}) df['Dates'] = df['Dates'].apply(pd.to_datetime) tick_label = dict(zip(df['nb_days'],df['Dates'].apply(lambda x: x.strftime('%Y-%m-%d')))) #My custom xtick label #Plot fig,ax = plt.subplots(figsize=(6,6)) ax = sns.boxplot(x='nb_days',y='score',data=df,color=None) # iterate over boxes to change color for i,box in enumerate(ax.artists): box.set_edgecolor('red') box.set_facecolor('white') sns.stripplot(x='nb_days',y='score',data=df,color='black') ticks = sorted(df['nb_days'].unique()) labels = [tick_label.get(t, ticks[i]) for i,t in enumerate(ticks)] ax.set_xticklabels(labels) plt.tight_layout() plt.show() plt.close() Here is the desired output.
You can do that by adding these lines in place of ax.set_xticklabels(labels) new_labels=["{}\n{}".format(a_, b_) for a_, b_ in zip(ticks, labels)] ax.set_xticklabels(new_labels) Output
Try this: import pandas as pd import matplotlib.pyplot as plt import seaborn as sns df = pd.DataFrame({'nb_days':[20,20,20,25,25,20,32,32,25,32,32], 'Dates':['2022-05-08','2022-05-08','2022-05-08','2022-05-13','2022-05-13','2022-05-08','2022-05-20','2022-05-20','2022-05-13','2022-05-20','2022-05-20'], 'score':[3,3.5,3.4,2,2.2,3,5,5.2,4,4.3,5]}) df['Dates'] = df['Dates'].apply(pd.to_datetime) tick_label = dict(zip(df['nb_days'],df['Dates'].apply(lambda x: x.strftime('%Y-%m-%d')))) #My custom xtick label #Plot fig,ax = plt.subplots(figsize=(6,6)) ax = sns.boxplot(x='nb_days',y='score',data=df,color=None) # iterate over boxes to change color for i,box in enumerate(ax.artists): box.set_edgecolor('red') box.set_facecolor('white') sns.stripplot(x='nb_days',y='score',data=df,color='black') ticks = sorted(df['nb_days'].unique()) labels = ["{}\n".format(t)+tick_label.get(t, ticks[i]) for i, t in enumerate(ticks)] ax.set_xticklabels(labels) plt.tight_layout() plt.show() plt.close()
Reproduce simple pandas plot
I have a situation with my data. I like the behaviour of .plot() over a data frame. But sometimes it doesn't work, because the frequency of the time index is not an integer. But reproducing the plot in matplotlib is OK. Just ugly. The part that bother me the most is the settings of the x axis. The tick frequency and the limits. Is there any easy way that I can reproduce this behaviour in matplotlib? import numpy as np import pandas as pd import matplotlib.pyplot as plt # Create Data f = lambda x: np.sin(0.1*x) + 0.1*np.random.randn(1,x.shape[0]) x = np.arange(0,217,0.001) y = f(x) # Create DataFrame data = pd.DataFrame(y.transpose(), columns=['dp'], index=None) data['t'] = pd.date_range('2021-01-01 14:32:09', periods=len(data['dp']),freq='ms') data.set_index('t', inplace=True) # Pandas plot() data.plot() # Matplotlib plot (ugly x-axis) plt.plot(data.index,data['dp']) EDIT: Basically, what I want to achieve is a similar spacing in the xtics labels, and the tight margin adjust of the values. Legends and axis title, I can do them Pandas output Matplotlib output Thanks
You can use some matplotlib date utilities: Figure.autofmt_xdate() to unrotate and center the date labels Axis.set_major_locator() to change the interval to 1 min Axis.set_major_formatter() to reformat as %H:%M fig, ax = plt.subplots() ax.plot(data.index, data['dp']) import matplotlib.dates as mdates fig.autofmt_xdate(rotation=0, ha='center') ax.xaxis.set_major_locator(mdates.MinuteLocator(interval=1)) ax.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M')) # uncomment to remove the first `xtick` # ax.set_xticks(ax.get_xticks()[1:])
Fix x-axis scale seaborn factorplot
I'm attempting to make a figure that shows two plots, with each plot separated based on a set of categorical data. However, although I can make the graph, I cant figure out how to get the x-axis to be properly spaced. I want the x-axis to start before the first value (want axis to start at 60 [first value = 63]) and end after the last (want axis to end at 95 [last value = 92.1]), with xticks going up in 5's. Any help is much appreciated! Thanks in advance! import pandas as pd import matplotlib.pyplot as plt import matplotlib.axes import seaborn as sns Temperature = [63.0,63.3,63.6,63.9,64.2,64.5,64.8,65.2,65.5,65.8,66.1,66.4,66.7,67.0,67.3,67.7,68.0,68.3,68.6,68.9,69.2,69.5,69.9,70.2,70.5,70.8,71.1,71.4,71.8,72.1,72.4,72.7,73.0,73.4,73.7,74.0,74.3,74.6,74.9,75.2,75.6,75.9,76.2,76.5,76.9,77.2,77.5,77.8,78.1,78.5,78.8,79.1,79.4,79.7,80.1,80.4,80.7,81.0,81.3,81.6,81.9,82.3,82.6,82.9,83.2,83.5,83.8,84.1,84.4,84.8,85.1,85.4,85.7,86.0,86.3,86.6,86.9,87.2,87.5,87.8,88.1,88.4,88.7,89.0,89.3,89.6,89.8,90.1,90.4,90.7,91.0,91.2,91.5,91.8,92.1,63.0,63.3,63.6,63.9,64.2,64.5,64.8,65.2,65.5,65.8,66.1,66.4,66.7,67.0,67.3,67.7,68.0,68.3,68.6,68.9,69.2,69.5,69.9,70.2,70.5,70.8,71.1,71.4,71.8,72.1,72.4,72.7,73.0,73.4,73.7,74.0,74.3,74.6,74.9,75.2,75.6,75.9,76.2,76.5,76.9,77.2,77.5,77.8,78.1,78.5,78.8,79.1,79.4,79.7,80.1,80.4,80.7,81.0,81.3,81.6,81.9,82.3,82.6,82.9,83.2,83.5,83.8,84.1,84.4,84.8,85.1,85.4,85.7,86.0,86.3,86.6,86.9,87.2,87.5,87.8,88.1,88.4,88.7,89.0,89.3,89.6,89.8,90.1,90.4,90.7,91.0,91.2,91.5,91.8,92.1] Derivative = [0.0495,0.0507,0.0525,0.0548,0.0570,0.0579,0.0579,0.0574,0.0574,0.0576,0.0581,0.0587,0.0593,0.0592,0.0584,0.0580,0.0579,0.0580,0.0582,0.0588,0.0592,0.0594,0.0588,0.0581,0.0578,0.0579,0.0580,0.0579,0.0582,0.0581,0.0579,0.0574,0.0571,0.0563,0.0548,0.0538,0.0536,0.0540,0.0544,0.0551,0.0556,0.0551,0.0542,0.0535,0.0536,0.0542,0.0564,0.0623,0.0748,0.0982,0.1360,0.1897,0.2550,0.3228,0.3807,0.4177,0.4248,0.3966,0.3365,0.2558,0.1713,0.0971,0.0438,0.0140,0.0034,0.0028,0.0048,0.0058,0.0057,0.0050,0.0042,0.0038,0.0039,0.0041,0.0038,0.0031,0.0023,0.0017,0.0014,0.0012,0.0015,0.0019,0.0020,0.0018,0.0017,0.0015,0.0014,0.0014,0.0015,0.0014,0.0013,0.0011,0.0007,0.0004,0.0011,0.0105,0.0100,0.0096,0.0090,0.0084,0.0081,0.0077,0.0071,0.0066,0.0063,0.0064,0.0060,0.0057,0.0055,0.0054,0.0051,0.0047,0.0046,0.0042,0.0037,0.0035,0.0040,0.0043,0.0039,0.0032,0.0028,0.0028,0.0027,0.0029,0.0034,0.0038,0.0034,0.0027,0.0024,0.0021,0.0017,0.0015,0.0016,0.0015,0.0011,0.0008,0.0012,0.0019,0.0025,0.0027,0.0026,0.0019,0.0012,0.0010,0.0014,0.0016,0.0014,0.0010,0.0007,0.0007,0.0010,0.0017,0.0021,0.0020,0.0013,0.0012,0.0013,0.0014,0.0015,0.0018,0.0017,0.0012,0.0013,0.0018,0.0028,0.0031,0.0033,0.0027,0.0022,0.0015,0.0016,0.0022,0.0026,0.0026,0.0019,0.0012,0.0006,0.0007,0.0011,0.0016,0.0014,0.0010,0.0009,0.0012,0.0015,0.0014,0.0008,0.0001,-0.0003,0.0002] Category = ["a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b"] df = pd.DataFrame({"Temperature": Temperature, "Derivative": Derivative, "Category" : Category}) g = sns.factorplot(x="Temperature", y="Derivative", data=df, col="Category") g.set_xticklabels(step=10)
All the desired feature you describe suggest that using a factorplot here is absolutely the wrong choice. Instead use a normal matplotlib plot and then set the limits as usual, plt.xlim(60,95). import pandas as pd import matplotlib.pyplot as plt Temperature = [63.0,63.3,63.6,63.9,64.2,64.5,64.8,65.2,65.5,65.8,66.1,66.4,66.7,67.0,67.3,67.7,68.0,68.3,68.6,68.9,69.2,69.5,69.9,70.2,70.5,70.8,71.1,71.4,71.8,72.1,72.4,72.7,73.0,73.4,73.7,74.0,74.3,74.6,74.9,75.2,75.6,75.9,76.2,76.5,76.9,77.2,77.5,77.8,78.1,78.5,78.8,79.1,79.4,79.7,80.1,80.4,80.7,81.0,81.3,81.6,81.9,82.3,82.6,82.9,83.2,83.5,83.8,84.1,84.4,84.8,85.1,85.4,85.7,86.0,86.3,86.6,86.9,87.2,87.5,87.8,88.1,88.4,88.7,89.0,89.3,89.6,89.8,90.1,90.4,90.7,91.0,91.2,91.5,91.8,92.1,63.0,63.3,63.6,63.9,64.2,64.5,64.8,65.2,65.5,65.8,66.1,66.4,66.7,67.0,67.3,67.7,68.0,68.3,68.6,68.9,69.2,69.5,69.9,70.2,70.5,70.8,71.1,71.4,71.8,72.1,72.4,72.7,73.0,73.4,73.7,74.0,74.3,74.6,74.9,75.2,75.6,75.9,76.2,76.5,76.9,77.2,77.5,77.8,78.1,78.5,78.8,79.1,79.4,79.7,80.1,80.4,80.7,81.0,81.3,81.6,81.9,82.3,82.6,82.9,83.2,83.5,83.8,84.1,84.4,84.8,85.1,85.4,85.7,86.0,86.3,86.6,86.9,87.2,87.5,87.8,88.1,88.4,88.7,89.0,89.3,89.6,89.8,90.1,90.4,90.7,91.0,91.2,91.5,91.8,92.1] Derivative = [0.0495,0.0507,0.0525,0.0548,0.0570,0.0579,0.0579,0.0574,0.0574,0.0576,0.0581,0.0587,0.0593,0.0592,0.0584,0.0580,0.0579,0.0580,0.0582,0.0588,0.0592,0.0594,0.0588,0.0581,0.0578,0.0579,0.0580,0.0579,0.0582,0.0581,0.0579,0.0574,0.0571,0.0563,0.0548,0.0538,0.0536,0.0540,0.0544,0.0551,0.0556,0.0551,0.0542,0.0535,0.0536,0.0542,0.0564,0.0623,0.0748,0.0982,0.1360,0.1897,0.2550,0.3228,0.3807,0.4177,0.4248,0.3966,0.3365,0.2558,0.1713,0.0971,0.0438,0.0140,0.0034,0.0028,0.0048,0.0058,0.0057,0.0050,0.0042,0.0038,0.0039,0.0041,0.0038,0.0031,0.0023,0.0017,0.0014,0.0012,0.0015,0.0019,0.0020,0.0018,0.0017,0.0015,0.0014,0.0014,0.0015,0.0014,0.0013,0.0011,0.0007,0.0004,0.0011,0.0105,0.0100,0.0096,0.0090,0.0084,0.0081,0.0077,0.0071,0.0066,0.0063,0.0064,0.0060,0.0057,0.0055,0.0054,0.0051,0.0047,0.0046,0.0042,0.0037,0.0035,0.0040,0.0043,0.0039,0.0032,0.0028,0.0028,0.0027,0.0029,0.0034,0.0038,0.0034,0.0027,0.0024,0.0021,0.0017,0.0015,0.0016,0.0015,0.0011,0.0008,0.0012,0.0019,0.0025,0.0027,0.0026,0.0019,0.0012,0.0010,0.0014,0.0016,0.0014,0.0010,0.0007,0.0007,0.0010,0.0017,0.0021,0.0020,0.0013,0.0012,0.0013,0.0014,0.0015,0.0018,0.0017,0.0012,0.0013,0.0018,0.0028,0.0031,0.0033,0.0027,0.0022,0.0015,0.0016,0.0022,0.0026,0.0026,0.0019,0.0012,0.0006,0.0007,0.0011,0.0016,0.0014,0.0010,0.0009,0.0012,0.0015,0.0014,0.0008,0.0001,-0.0003,0.0002] Category = ["a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","a","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b","b"] df = pd.DataFrame({"Temperature": Temperature, "Derivative": Derivative, "Category" : Category}) for n, data in df.groupby("Category"): plt.plot(data["Temperature"],data["Derivative"] , marker="o", label=n) plt.xlim(60,95) plt.legend() plt.show() Or if subplots are desired, fig,axes = plt.subplots(ncols=len(df["Category"].unique()), sharey=True) for ax,(n, data) in zip(axes,df.groupby("Category")): ax.plot(data["Temperature"],data["Derivative"] , marker="o", label=n) ax.set_title("Category {}".format(n)) ax.set_xlim(60,95) plt.show() Finally, you may use a seaborn FacetGrid onto which you plot your data with a plot: g = sns.FacetGrid(df, col="Category") g.map(plt.plot, "Temperature", "Derivative",marker="o",) for ax in g.axes.flat: ax.set_xlim(60,95) plt.show()
Unable to show Pandas dateindex on a matplotlib x axis
I'm trying to build matplotlib charts whose x-axis is a dateIndex from a pandas dataframe. Trying to mimic some examples from matplotlib, I've been unsuccessful. The xaxis ticks and labels never appear. I thought maybe matplotlib wasn't properly digesting the pandas index, so I converted it to ordinal with the matplotlib date2num helper function, but that gave the same result. # https://matplotlib.org/api/dates_api.html # https://matplotlib.org/examples/api/date_demo.html import datetime as dt import matplotlib.dates as mdates import matplotlib.cbook as cbook import matplotlib.dates as mpd years = mdates.YearLocator() # every year months = mdates.MonthLocator() # every month yearsFmt = mdates.DateFormatter('%Y') majorLocator = years majorFormatter = yearsFmt #FormatStrFormatter('%d') minorLocator = months y1 = np.arange(100)*0.14+1 y2 = -(np.arange(100)*0.04)+12 """neither of these indices works""" x = pd.date_range(start='4/1/2012', periods=len(y1)) #x = map(mpd.date2num, pd.date_range(start='4/1/2012', periods=len(y1))) fig, ax = plt.subplots() ax.plot(x,y1) ax.plot(x,y2) ax.xaxis.set_major_locator(years) ax.xaxis.set_major_formatter(yearsFmt) ax.xaxis.set_minor_locator(months) datemin = x[0] datemax = x[-1] ax.set_xlim(datemin, datemax) fig.autofmt_xdate() plt.show()
The problem is the following. pd.date_range(start='4/1/2012', periods=len(y1)) creates dates from the first of April 2012 to the 9th of July 2012. Now you set the major locator to be a YearLocator. This means, that you want to have a tick for each year on the axis. However, all dates are within the same year 2012. So there is no major tick to be shown within the plot range. The suggestion would be to use a MonthLocator instead, such that the first of each month is ticked. Also if would make sense to use a formatter, which actually shows the months, e.g. '%b %Y'. You may use a DayLocator for the minor ticks, if you want, to show the small tickmarks for each day. ax.xaxis.set_major_locator(mdates.MonthLocator()) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y')) ax.xaxis.set_minor_locator(mdates.DayLocator()) Complete example: import pandas as pd import numpy as np import matplotlib.pyplot as plt import matplotlib.dates as mdates y1 = np.arange(100)*0.14+1 y2 = -(np.arange(100)*0.04)+12 x = pd.date_range(start='4/1/2012', periods=len(y1)) fig, ax = plt.subplots() ax.plot(x,y1) ax.plot(x,y2) ax.xaxis.set_major_locator(mdates.MonthLocator()) ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y')) ax.xaxis.set_minor_locator(mdates.DayLocator()) fig.autofmt_xdate() plt.show()
You could use pd.DataFrame.plot to handle most of that df = pd.DataFrame(dict( y1=y1, y2=y2 ), index=x) df.plot()
Matplotlib pyplot - tick control and showing date
My matplotlib pyplot has too many xticks - it is currently showing each year and month for a 15-year period, e.g. "2001-01", but I only want the x-axis to show the year (e.g. 2001). The output will be a line graph where x-axis shows dates and the y-axis shows the sale and rent prices. # Defining the variables ts1 = prices['Month'] # eg. "2001-01" and so on ts2 = prices['Sale'] ts3 = prices['Rent'] # Reading '2001-01' as year and month ts1 = [dt.datetime.strptime(d,'%Y-%m').date() for d in ts1] plt.figure(figsize=(13, 9)) # Below is where it goes wrong. I don't know how to set xticks to show each year. plt.xticks(ts1, rotation='vertical') plt.xlabel('Year') plt.ylabel('Price') plt.plot(ts1, ts2, 'r-', ts1, ts3, 'b.-') plt.gcf().autofmt_xdate() plt.show()
Try removing the plt.xticks function call altogether. matplotlib will then use the default AutoDateLocator function to find the optimum tick locations. Alternatively if the default includes some months which you don't want then you can use matplotlib.dates.YearLocator which will force the ticks to be years only. You can set the locator as shown below in a quick example: import matplotlib.pyplot as plt import matplotlib.dates as mdate import numpy as np import datetime as dt x = [dt.datetime.utcnow() + dt.timedelta(days=i) for i in range(1000)] y = range(len(x)) plt.plot(x, y) locator = mdate.YearLocator() plt.gca().xaxis.set_major_locator(locator) plt.gcf().autofmt_xdate() plt.show()
You can do this with plt.xticks. As an example, here I have set the xticks frequency to display every three indices. In your case, you would probably want to do so every twelve indices. import numpy as np import matplotlib.pyplot as plt x = np.arange(10) y = np.random.randn(10) plt.plot(x,y) plt.xticks(np.arange(min(x), max(x)+1, 3)) plt.show() In your case, since you are using dates, you can replace the argument of the second to last line above with something like ts1[0::12], which will select every 12th element from ts1 or np.arange(0, len(dates), 12) which will select every 12th index corresponding to the ticks you want to show.