rll
rll

Reputation: 5587

Matplotlib not showing xlabel in top two subplots when using secondary y axis

This question is very similar to this other one, but the provided answer does not solve my issue as it is not exactly the same. Also the problem has been referred in this one, but no answer was provided. I am hoping this example will help someone point me out a workaround.

The problem is when I use a secondary y axis (both with pandas and using twinx), the xlabels and xticklabels disappear on the top subplots.

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame([[1,2,4,6],[1,2,6,10],[2,4,12,12],[2,4,12,14],
               [3,8,14,16],[3,8,14,18],[4,10,16,20],[4,10,16,24]], 
              columns =['A','B','C','D'])

fig, axes = plt.subplots(2,2)

for xx, ax in zip(['A','B','C'], axes.flatten()):
    meandf = df.groupby(xx).mean()
    df.plot(xx, 'D', ax = ax, legend=False)

    #adding the secondary_y makes x labels and ticklabels disappear on top subplots
    #without secondary_y it will show the labels and ticklabels
    meandf.plot(meandf.index, 'D', secondary_y='D', ax = ax)

    #forcing does not help
    ax.set_xlabel(xx)

# typically it is a matter of using tight_layout, but does not solve
# setting a bigger space between the rows does not solve it either
plt.tight_layout()

Upvotes: 2

Views: 2230

Answers (1)

Paul H
Paul H

Reputation: 68126

KeyErrors aside, sticking with raw matplotlib is probably your best bet:

import pandas as pd
import matplotlib.pyplot as plt

df = pd.DataFrame(
    [[1, 2, 4, 6], [1, 2, 6, 10], [2, 4, 12, 12], [2, 4, 12, 14],
     [3, 8, 14, 16], [3, 8, 14, 18], [4, 10 ,16, 20], [4, 10 ,16, 24]], 
    columns =['A', 'B', 'C', 'D']
)

fig, axes = plt.subplots(2, 2)

for xx, ax1 in zip(['A','B','C'], axes.flatten()):
    meandf = df.groupby(xx).mean()

    # explicitly create and save the secondary axis  
    ax2 = ax1.twinx()

    # plot on the main ax
    ax1.plot(xx, 'D', 'ko', data=df)

    # plot on the secondary ax
    ax2.plot('D', 'gs', data=meandf)

    # set the label 
    ax1.set_xlabel(xx)

fig.tight_layout()

enter image description here

Upvotes: 1

Related Questions