fgypas
fgypas

Reputation: 326

Multiple subplots in triangular form using matplotlib

I have 6 lists and I want to create scatterplots for all possible combinations. This means that I want to create n(n-1)/2 combinations, so 15 plots. I have done this correctly based on the following script.

for i in d:
    for j in d:
        if(j>i):
            plt.cla()   # Clear axis
            plt.clf()   # Clear figure
            correlation_coefficient = str(np.corrcoef(d[i], d[j])[0][1])
            plt.scatter(d[i],d[j])
            plt.xlabel(names[i])
            plt.ylabel(names[j])
            plt.title('Correlation Coefficient: '+correlation_coefficient)
            plt.grid()
            plt.savefig(names[i]+"_"+names[j]+".png")

I want to save all these plots in one figure using subplot, where the first row will have the combinations (0,1) (0,2) (0,3) (0,4) (0,5) the second row (1,2) (1,3) (1,4) (1,5) the third row (2,3) (2,4) (2,5) etc.

So the final outcome will be a figure containing subplots in triangular form.

Update:

If I use subplots (code below) I was able to get somehow the result, but it is not optimal as I create a 6x6 frame whereas you can do it with 5x5.

fig = plt.figure()
cnt = 0

# Create scatterplots for all pairs
for i in d:
    for j in d:
        if(i>=j):
            cnt=cnt+1
        if(j>i):
            cnt += 1
            fig.add_subplot(6,6,cnt)   #top left
            correlation_coefficient = str(np.corrcoef(d[i], d[j])[0][1])
            plt.scatter(np.log(d[i]),np.log(d[j]))

fig.savefig('test.png')

Upvotes: 3

Views: 1770

Answers (1)

cphlewis
cphlewis

Reputation: 16239

With gridspec:

from matplotlib import pyplot as plt

fig = plt.figure()

data = [(1,2,3),(8,2,3),(0,5,2),(4,7,1),(9,5,2),(8,8,8)]
plotz = len(data)
for i in range(plotz-1):
    for j in range(plotz):
        if(j>i) :
            print(i,j)
            ax = plt.subplot2grid((plotz-1, plotz-1), (i,j-1))
            ax.xaxis.set_ticklabels([])
            ax.yaxis.set_ticklabels([])
            plt.scatter(data[i],data[j]) # might be nice with shared axis limits

fig.show()

Not-redundant plots of combinations from a 6-element list

With add_subplot, you've hit an oddity inherited from MATLAB, which 1-indexes the subplot count. (Also you have some counting errors.) Here's an example that just keeps track of the various indices:

from matplotlib import pyplot as plt

fig = plt.figure()
count = 0

data = [(1,2,3),(8,2,3),(0,5,2),(4,7,1),(9,5,2),(8,8,8)]
plotz = len(data)
for i in range(plotz-1):
    for j in range(plotz):
        if(j>i):
            print(count, i,j, count -i)
            ax = fig.add_subplot(plotz-1, plotz-1, count-i)
            ax.xaxis.set_ticklabels([])
            ax.yaxis.set_ticklabels([])
            plt.text(.15, .5,'i %d, j %d, c %d'%(i,j,count))
        count += 1

fig.show()

N.b.: the error from doing the obvious (your original code with add_subplot(5,5,cnt)) was a good hint:

...User/lib/python2.7/site-packages/matplotlib/axes.pyc in init(self, fig, *args, **kwargs)

9249 self._subplotspec = GridSpec(rows, cols)[num[0] - 1:num1]

9250 else:

-> 9251 self._subplotspec = GridSpec(rows, cols)[int(num) - 1]

9252 # num - 1 for converting from MATLAB to python indexing

Upvotes: 0

Related Questions