Setting physically square subplots in Matplotlib 3 with shared axes

时间:2019-01-09 21:47:38

标签: python matplotlib

I am trying to create a similar plot to what is done by seaborn, but in native matplotlib.

I am plotting every Series in a data frame against every other series in a matrix of plots.

So far I've plotted it, marked the outer axes, and set the axes to be shared along columns and row (as this works with the data the best).

The final step I am failing to manage is to make all the plots physically square in dimension. The following code:

#scatter matrix

def plot_scatter_matrix(data):
    dim = len(data.columns.values)
    fig, axs = newfigure(dim, dim, sharex='col', sharey='row', figsize=(10,10))
    fig.tight_layout()
    for row, iname in enumerate(data.columns.values):
        for col, jname in enumerate(data.columns.values):
            axs[row,col].scatter(data[jname], data[iname])
            if col == 0:
                axs[row,col].set_ylabel(iname)
            if row == len(data.columns.values)-1:
                axs[row,col].set_xlabel(jname)

    return fig, axs

fig, axs = plot_scatter_matrix(ndata)
plt.show()

achieves this (only top half pictured):

im1

I have attempted to use axs[row,col].set_aspect(1.0, adjustable='box', share=True) after the call to scatter() however it simply resulted in this:

im2

As you can see, some managed to become physically square but they are all different sizes.

Having looked extensively through documentation and other questions I am stumped. Doesn't make it easier when other methods for this sort of thing have been deprecated over past versions.

1 个答案:

答案 0 :(得分:0)

If some axes become square by using set_aspect(1.0) (or the equivalent set_aspect("equal")) that's more or less coincidence and would only happen when the diffence of axis limits is actually equal; e.g. when the data ranges for x and y are the same.

Of course you could share all axes, not just column- or row-wise. That would ensure all axes to be of equal shape - but not necessarily square.

The requirement for square axes is that the aspect is the quotient of the x- and y range.

ax.set_aspect(np.diff(ax.get_xlim())/np.diff(ax.get_ylim()))

Also see: How to make sure that both x and y axes of plot are of equal sizes?

Another option is to restrict the space the subplots have via the subplot parameters as shown in this answer to python interplay between axis('square') and set_xlim.