Custom xlabel rotation issue with pandas plot when using secondary_y

Question:

I want to show the x labels rotated 45 degrees. I tired the following code, but it still shows the x labels with 0 rotation.

How can the labels be rotated?

df_final = pd.DataFrame({'Count':[8601,188497,808,7081,684,15601,75,12325],
                         'Average': [0.128,0.131,0.144,.184,.134,.152,0.139,0.127]})
width = 0.8
df_final['Count'].plot(kind='bar', width = width)
df_final['Average'].plot(secondary_y=True)
ax = plt.gca()
ax.set_xticklabels(['One', 'Two', 'Three', 'Four', 'Five','Six','Seven','Eight'],rotation = 45)
plt.show()
Asked By: John

||

Answers:

Just change the place of ax = plt.gca() Can you try below code :

df_final = pd.DataFrame({'Count':[8601,188497,808,7081,684,15601,75,12325],
                         'Average': [0.128,0.131,0.144,.184,.134,.152,0.139,0.127]})
width = 0.8
ax = plt.gca()
df_final['Count'].plot(kind='bar', width = width)
df_final['Average'].plot(secondary_y=True)
ax.set_xticklabels(['One', 'Two', 'Three', 'Four', 'Five','Six','Seven','Eight'],rotation = 45)
plt.show()
Answered By: Ugur Yigit
  • pandas.DataFrame.plot returns matplotlib.axes.Axes. As such, assign the Axes of the first plot to a variable, ax.
    • ax = plt.gca() is not required, but would go directly before df_final['Average'].plot(...) if used.
  • The settings of the second plot take precedence, therefore the rotation should be set with rot=45 in the second plot call, or in set_xticklabels.
  • Also see Add label values to bar chart and line chart for adding labels.
  • Tested in python 3.11, pandas 1.5.3, matplotlib 3.7.0

Sample Data and Setup

import pandas as pd

df_final = pd.DataFrame({'Count': [8601, 188497, 808, 7081, 684, 15601, 75, 12325],
                         'Average': [0.128, 0.131, 0.144, 0.184, 0.134, 0.152, 0.139, 0.127]})

width = 0.8

labels = ['One', 'Two', 'Three', 'Four', 'Five', 'Six', 'Seven', 'Eight']

Option 1

# assign the plot to ax
ax = df_final['Count'].plot(kind='bar', width=width, figsize=(9, 6), legend=True)

# place the secondary plot on ax
df_final['Average'].plot(secondary_y=True, ax=ax, color='r', legend=True)  # optionally add rot=45 here

# set the custom xtick labels and rotate
_ = ax.set_xticklabels(labels, rotation=45)  # remove rotation=45 if using rot=45 in the previous line

Option 2

# set the index values to the labels, providing the order corresponds to the DataFrame
df_final.index = labels

# initial plot
ax = df_final['Count'].plot(kind='bar', width=width, figsize=(9, 6), legend=True)

# secondary plot and specify rotation
df_final['Average'].plot(secondary_y=True, ax=ax, rot=45, color='r', legend=True)

Option 3

  • Create the DataFrame with a custom index using the index parameter, and then plot like Option 2 without df_final.index = labels.
df_final = pd.DataFrame({'Count': [8601, 188497, 808, 7081, 684, 15601, 75, 12325],
                         'Average': [0.128, 0.131, 0.144, 0.184, 0.134, 0.152, 0.139, 0.127]},
                        index=labels)

enter image description here

Answered By: Trenton McKinney
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.