1

I'm plotting a visualization with two y axes each representing a dataframe column. I used one of the dataframe's (both dataframes have the same index) index as the x-axis, however the xticks labels are not showing correctly. I should have years from 2000 to 2018

I used the following code to create the plot:

fig, ax1 = plt.subplots()
ax2 = ax1.twinx()
ax1.plot(df1.index, df1, 'g-')
ax2.plot(df1.index, df2, 'b-')
ax1.set_xlabel('X data')
ax1.set_ylabel('Y1 data', color='g')
ax2.set_ylabel('Y2 data', color='b')
plt.show()

the index of df1 is as follows:

Index(['2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008',
       '2009', '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016',
       '2017', '2018'],
      dtype='object')

Here's a small snippet of the two dfs:

df1.head()
            gdp
2000    1.912873
2001    7.319967
2002    3.121450
2003    5.961162
2004    4.797018
df2.head()
        lifeex
2000    68.684
2001    69.193
2002    69.769
2003    70.399
2004    71.067

The plot looks like: df index

I tried different solutions including the one in Set Xticks frequency to dataframe index but none has succeeded to get all years showing. I really appreciate if someone can help. thanks in advance

When I try ax1.set_xticks(df1.index) I get the following error: '<' not supported between instances of 'numpy.ndarray' and 'str'

houda benhar
  • 101
  • 1
  • 11
  • 1
    Can you add some sample data to this question? – Scott Boston Jan 09 '21 at 16:08
  • 3
    The problem is that matplotlib interprets the index as numerical data, not as datetime objects. As Scott Boston said, without sample data, one cannot give good advice. Please read [How to make good reproducible pandas examples](https://stackoverflow.com/questions/20109391/how-to-make-good-reproducible-pandas-examples) and add your data using one of the suggested methods. – Mr. T Jan 09 '21 at 16:28
  • You can try converting your years to Datetime objects via `pd.to_datetime()`. Also, I recommend [Plotly](https://plotly.com/python/time-series/) for plotting with Datetime objects in your x axis. It takes care of the appropriate scaling and tick marks. – Jacob K Jan 09 '21 at 17:08
  • Thank you everyone for your help. I tried the following code and it worked `years = list(df1.index) for i in range(0, len(years)): years[i] = int(years[i]) ax1.xaxis.set_ticks(years) plt.setp(ax1.get_xticklabels(), rotation=30, horizontalalignment='right')` – houda benhar Jan 10 '21 at 12:46
  • Glad it is solved. You can [answer your own question and accept it.](https://stackoverflow.com/help/self-answer) – Mr. T Jan 10 '21 at 12:49

2 Answers2

0

I couldn't duplicate your issue (mpl.version = 3.2.2):

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

df1 = pd.DataFrame({'col1':np.random.randint(1,7 , 19)}, 
                   index=[str(i) for i in range(2000,2019)])

print(df1.index)

df2 = pd.Series(np.linspace(69,78, 19))

fig, ax1 = plt.subplots(figsize=(15,8))
ax2 = ax1.twinx()
ax1.plot(df1.index, df1, 'g-')
ax2.plot(df1.index, df2, 'b-')
ax1.set_xlabel('X data')
ax1.set_ylabel('Y1 data', color='g')
ax2.set_ylabel('Y2 data', color='b')
plt.show()

Output:

Index(['2000', '2001', '2002', '2003', '2004', '2005', '2006', '2007', '2008',
       '2009', '2010', '2011', '2012', '2013', '2014', '2015', '2016', '2017',
       '2018'],
      dtype='object')

enter image description here

Scott Boston
  • 147,308
  • 15
  • 139
  • 187
0

The following code solved the problem for me:

years = list(df1.index) 
for i in range(0, len(years)):     
   years[i] = int(years[i]) 
ax1.xaxis.set_ticks(years)
houda benhar
  • 101
  • 1
  • 11