Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

alignment of stacked subplots

EDIT:

I found myself an answer (see below) how to align the images within their subplots:

for ax in axes:
    ax.set_anchor('W')

EDIT END

I have some data I plot with imshow. It's long in x direction, so I break it into multiple lines by plotting slices of the data in vertically stacked subplots. I am happy with the result but for the last subplot (not as wide as the others) which I want left aligned with the others.

The code below is tested with Python 2.7.1 and matplotlib 1.2.x.

#! /usr/bin/env python

import matplotlib.pyplot as plt
import numpy as np

x_slice = [0,3]
y_slices = [[0,10],[10,20],[20,30],[30,35]]
d = np.arange(35*3).reshape((35,3)).T
vmin = d.min()
vmax = d.max()
fig, axes = plt.subplots(len(y_slices), 1)


for i, s in enumerate(y_slices):
    axes[i].imshow( 
        d[ x_slice[0]:x_slice[1], s[0]:s[1] ], 
        vmin=vmin, vmax=vmax,
        aspect='equal',
        interpolation='none'
    )

plt.show()

results in

vertically stacked subplots, last centered

Given the tip by Zhenya I played around with axis.get/set_position. I tried to half the width but I don't understand the effect it has

for ax in axes:
    print ax.get_position()

p3 = axes[3].get_position().get_points()
x0, y0 = p3[0]
x1, y1 = p3[1]
# [left, bottom, width, height]
axes[3].set_position([x0, y0, (x1-x0)/2, y1-y0])

enter image description here

get_position gives me the bbox of each subplot:

for ax in axes:
    print ax.get_position()

Bbox(array([[ 0.125     ,  0.72608696],
            [ 0.9       ,  0.9       ]]))
Bbox(array([[ 0.125     ,  0.5173913 ],
            [ 0.9       ,  0.69130435]]))
Bbox(array([[ 0.125     ,  0.30869565],
            [ 0.9       ,  0.4826087 ]]))
Bbox(array([[ 0.125     ,  0.1       ],
            [ 0.9       ,  0.27391304]]))

so all the subplots have the exact same horizontal extent (0.125 to 0.9). Judging from the narrower 4th subplot the image inside the subplot is somehow centered.

Let's look at the AxesImage objects:

for ax in axes:
    print ax.images[0]

AxesImage(80,348.522;496x83.4783)
AxesImage(80,248.348;496x83.4783)
AxesImage(80,148.174;496x83.4783)
AxesImage(80,48;496x83.4783)

again, the same horizontal extent for the 4th image too.

Next try AxesImage.get_extent():

for ax in axes:
    print ax.images[0].get_extent()

# [left, right, bottom, top]
(-0.5, 9.5, 2.5, -0.5)
(-0.5, 9.5, 2.5, -0.5)
(-0.5, 9.5, 2.5, -0.5)
(-0.5, 4.5, 2.5, -0.5)

there is a difference (right) but the left value is the same for all so why is the 4th one centered then?

EDIT: They are all centered...

like image 872
arose Avatar asked Jun 04 '12 12:06

arose


People also ask

How do you add a gap between subplots?

We can use the plt. subplots_adjust() method to change the space between Matplotlib subplots. The parameters wspace and hspace specify the space reserved between Matplotlib subplots. They are the fractions of axis width and height, respectively.

How do you plot multiple subplots in Python?

To create multiple plots use matplotlib. pyplot. subplots method which returns the figure along with Axes object or array of Axes object. nrows, ncols attributes of subplots() method determine the number of rows and columns of the subplot grid.


1 Answers

Axis.set_anchor works so far (I just hope I don't have to adjust too much manually now):

for ax in axes:
    ax.set_anchor('W')

enter image description here

like image 196
arose Avatar answered Sep 16 '22 21:09

arose