pythonmatplotlibseabornsubplot

Set suptitle and y-ticks in subplot


I have two different functions, each producing a plot.

list_soal = ['SalePrice', 'GrLivArea', 'GarageArea']

# fig,ax = plt.subplots(1, 3, sharey=True, figsize=(14,4))
def function1(ax):
    for i in range(len(list_soal)):
        plt.suptitle('Histogram for Non-Transfomed Data')    
        sns.histplot(df_train[list_soal[i]], kde=False, stat='density', bins = 30, ax=ax[i])
        sns.kdeplot(df_train[list_soal[i]], ax=ax[i])

# fig,ax = plt.subplots(1, 3, sharey=True, figsize=(14,4))
def function2(ax):
    for i in range(len(list_soal)):
        plt.suptitle('Histogram for Transfomed Data')
        sns.histplot(np.log10(df_train[list_soal[i]]), kde=False, stat='density', bins = 30, ax=ax[i])
        sns.kdeplot(np.log10(df_train[list_soal[i]]), ax=ax[i])

fig,ax = plt.subplots(2, 3, figsize=(20,8), sharey=True)

function1(ax[0])
function2(ax[1])

plt.show()

I want to unify the y-axis on every row. So I declare sharey=True in line 17. The result is shown like this: enter image description here

But if I remove sharey=True in line 17, it's shown like this: enter image description here

I also declare suptitle in function2. But it didn't show the title.

I'm wondering how to set the title and unify the y-axis for every row in each function.


Solution

  • Instead of setting sharey=True, set sharey='row'. This will tell matplotlib that each row of subplots should share a y-axis.

    fig, ax = plt.subplots(2, 3, figsize=(20,8), sharey='row')
    

    From the docs:

    sharex, sharey bool or {'none', 'all', 'row', 'col'}, default: False

    Controls sharing of properties among x (sharex) or y (sharey) axes:

    True or 'all': x- or y-axis will be shared among all subplots.

    False or 'none': each subplot x- or y-axis will be independent.

    'row': each subplot row will share an x- or y-axis.

    'col': each subplot column will share an x- or y-axis.

    When subplots have a shared x-axis along a column, only the x tick labels of the bottom subplot are created. Similarly, when subplots have a shared y-axis along a row, only the y tick labels of the first column subplot are created. To later turn other subplots' ticklabels on, use tick_params.

    When subplots have a shared axis that has units, calling Axis.set_units will update each axis with the new units.

    Note that it is not possible to unshare axes.


    plt.suptitle sets the title for the overall figure. You are setting it twice by calling that function twice, which overwrites the title you set the first time. If you instead want a title for each row, you might consider just setting the title for the Axes in the centre of each row. For example:

    def function1(ax):
        ax[1].set_title('Histogram for Non-Transfomed Data')    
        for i in range(len(list_soal)):
            sns.histplot(df_train[list_soal[i]], kde=False, stat='density', bins = 30, ax=ax[i])
            sns.kdeplot(df_train[list_soal[i]], ax=ax[i])
    
    def function2(ax):
        ax[1].set_title('Histogram for Transfomed Data')
        for i in range(len(list_soal)):
            sns.histplot(np.log10(df_train[list_soal[i]]), kde=False, stat='density', bins = 30, ax=ax[i])
            sns.kdeplot(np.log10(df_train[list_soal[i]]), ax=ax[I])
    

    You may find that your title for the second row overlaps with the x-axis labels from the first row. To fix this, you can use

    fig.subplots_adjust(hspace=0.2)
    

    (and adjust that hspace value to suit your needs.