1

I would like to have a SQUARED scatter plot, and 4 subplots per figure. I figured out how to do that if the x and y axes have the same range:

f, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
for x in [ax1, ax2, ax3, ax4]:
    x.set_adjustable('box-forced')
    x.set_aspect('equal')

However, if the x and y axes have different ranges, this doesn't work because one unit in x gets the same length on the plot as one unit in y.

I've seen using plt.subplots_adjust() to change axis length, but I don't see how that works if I already have multiple subplots.

Any ideas? I am surprised how easy it is to set a figure size, and how tricky it is to set the axis length.

Thanks!

EDIT: Here is some code that shows the problem:

import matplotlib.pyplot as plt
import numpy as np

f, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
# All data within 0-25, 25-50, 50-75, 75-100 should be plotted on respective subplot
layers = [(ax4, (0., 25.)), (ax3, (25., 50.)), (ax2, (50.., 75.)), (ax1, (75., 100.))]

# make subplot squared:
for x in layers:
    x[0].set_adjustable('box-forced')
    x[0].set_aspect('equal')

# loop over multiple files containing data, here reproduced by creating a random number 100 times:
for x in np.arange(100):
    data = np.random.random(10)*100.
    for pl in layers:
        ii = np.where((data>=pl[1][0]) & (pl[1][1]>data))[0]
        pl[0].scatter(data[ii], data[ii])
plt.show()

This yields a plot with squared subplots: squared subplots (x axis and y axis have same range)1

Using the exact same code as above, but plotting data[ii] versus (data[ii])**2 gives plots with different axis ranges for x and y and changes the squared shape:

x and y have different ranges and the plots get squeezed 2

I would like to get the shape of plot 1 and the data of plot 2.

Thanks!

Therese
  • 63
  • 1
  • 2
  • 6
  • 1
    Can you provide a [mcve] which shows how it's not working and then using this, explain exactly how the plot should look like? (In this description focus on the result you want to achieve, not on what you think is a possible solution). – ImportanceOfBeingErnest May 04 '17 at 16:38

1 Answers1

2

You can set the aspect ratio to the ratio of the x and y limits of the plots. This will give you a square plot.

import matplotlib.pyplot as plt
import numpy as np

f, ((ax1, ax2), (ax3, ax4)) = plt.subplots(2, 2)
# All data within 0-25, 25-50, 50-75, 75-100 should be plotted on respective subplot
layers = [(ax4, (0., 25.)), (ax3, (25., 50.)), (ax2, (50., 75.)), (ax1, (75., 100.))]

# loop 
for x in np.arange(100):
    data = np.random.random(10)*100.
    for pl in layers:
        ii = np.where((data>=pl[1][0]) & (pl[1][1]>data))[0]
        pl[0].scatter(data[ii], data[ii])
        x0,x1 = pl[0].get_xlim()
        y0,y1 = pl[0].get_ylim()
        pl[0].set_aspect( (x1-x0)/(y1-y0) )
plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712