2017-02-26 2 views
1

Ich versuche mehrere Bilder in Unterplots zu plotten und entweder den Abstand zwischen Unterplottern (horizontal und vertikal) zu eliminieren oder zu steuern. Ich habe versucht, den Vorschlag in How to Use GridSpec... zu verwenden. Ich habe auch hier versucht, aber sie verwenden keine Unterplots(): space between subplots Ich bin in der Lage, den horizontalen Raum, aber nicht den vertikalen Raum mit dem, was ich tun, in den Code unten zu beseitigen. Bitte nicht als Duplikat markieren, da ich die anderen Posts ausprobiert habe und sie nicht tun, was ich will. Mein Code ist unten gezeigt. Vielleicht gibt es ein anderes Schlüsselwortargument, das ich im gridspec_kw Wörterbuch benötige? Ich möchte pltplots() nicht pltplot() dafür verwenden. Wenn es darauf ankommt, sind die Bilder nicht quadratisch, sie sind rechteckig. Ich habe auch versucht, f.tight_layout(h_pad=0,w_pad=0) vor plt.show() hinzuzufügen, aber es hat nichts geändert.Wie kombiniere ich gridspec mit pltplots(), um den Abstand zwischen den Zeilen der Unterplots zu eliminieren

def plot_image_array_with_angles(img_array,correct_angles,predict_angles, 
           fontsize=10,figsize=(8,8)): 
''' 
Imports: 
    import matplotlib.gridspec as gridspec 
    import numpy as np 
    import matplotlib.pyplot as plt 
''' 
num_images = len(img_array) 
grid = int(np.sqrt(num_images)) # will only show all images if square 
#f, axarr = plt.subplots(grid,grid,figsize=figsize) 
f, axarr = plt.subplots(grid,grid,figsize=figsize, 
         gridspec_kw={'wspace':0,'hspace':0}) 
im = 0 
for row in range(grid): 
    for col in range(grid): 
     axarr[row,col].imshow(img_array[im]) 
     title = 'cor = ' + str(correct_angles[im]) + ' pred = ' + str(predict_angles[im]) 
     axarr[row,col].set_title(title,fontsize=fontsize) 
     axarr[row,col].axis('off') # turns off all ticks 
     #axarr[row,col].set_aspect('equal') 
     im += 1 
plt.show() 
return 
+0

Haben Sie versucht plt.subplots_adjust? – user2660966

+0

ja, versucht, aber Sie müssen viel mehr tun als nur hspace und wspace. Der Post unten von @ImportanceOfBeingErnest funktioniert perfekt. Ich kann noch nicht upvote, aber dieser Beitrag beantwortet meine Frage vollständig. –

Antwort

3

Das Seitenverhältnis eines imshow Plot wird automatisch so eingestellt, dass Pixel im Bild quadriert. Diese Einstellung ist stärker als die subplots_adjust oder gridspec Einstellungen für den Abstand. Oder anders ausgedrückt, Sie können den Abstand zwischen Teilplots nicht direkt steuern, wenn für diese Teilplots der Aspekt auf "equal" gesetzt ist.

Die erste offensichtliche Lösung besteht darin, den Bildaspekt auf automatisch ax.set_aspect("auto") einzustellen. Dies löst das Problem des Unterplotting-Abstands, verzerrt jedoch die Bilder.

Die andere Option besteht darin, die Bildränder und die Bildgröße so anzupassen, dass der Abstand zwischen den Teilzeichnungen wie gewünscht ist.

Sagen wir figh und figw die Figur Höhe und Breite in Zoll sind, und s die subplot Breite in Zoll. Die Ränder sind, top, left und right (relativ zur Abbildungsgröße) und die Abstände hspace in vertikaler und wspace in horizontaler Richtung (relativ zur Größe der Subplots). Die Anzahl der Zeilen wird mit n und die Anzahl der Spalten m bezeichnet. Die aspect ist das Verhältnis zwischen Subplot (Bild) Höhe und Breite (aspect = image height/image width).

Dann können die Abmessungen über

fig, axes = plt.subplots(nrows=n, ncols=m, figsize=(figwidth, figheight)) 
plt.subplots_adjust(top=top, bottom=bottom, left=left, right=right, 
         wspace=wspace, hspace=hspace) 

Die jeweiligen Werte eingestellt werden, kann entsprechend berechnet werden:

enter image description here

Oder, wenn die Ränder sind die gleichen:

enter image description here

Ein Beispiel:

import matplotlib.pyplot as plt 

image = plt.imread("https://i.stack.imgur.com/9qe6z.png") 
aspect = image.shape[0]/float(image.shape[1]) 
print aspect 
n = 2 # number of rows 
m = 4 # numberof columns 
bottom = 0.1; left=0.05 
top=1.-bottom; right = 1.-left 
fisasp = (1-bottom-(1-top))/float(1-left-(1-right)) 
#widthspace, relative to subplot size 
wspace=0.15 # set to zero for no spacing 
hspace=wspace/float(aspect) 
#fix the figure height 
figheight= 3 # inch 
figwidth = (m + (m-1)*wspace)/float((n+(n-1)*hspace)*aspect)*figheight*fisasp 

fig, axes = plt.subplots(nrows=n, ncols=m, figsize=(figwidth, figheight)) 
plt.subplots_adjust(top=top, bottom=bottom, left=left, right=right, 
        wspace=wspace, hspace=hspace) 

for ax in axes.flatten(): 
    ax.imshow(image) 
    ax.set_title("title",fontsize=10) 
    ax.axis('off') 

plt.show() 

enter image description here

Verwandte Themen