Large Space after suptitle - python

There is large amount of space after suptitle and before the subplots. I'm unable to reduce the space between them and tight_layout() is not working. Can someone show a way to reduce the space between the suptitle and the subplots. I'm using the titanic dataset
Here is the image:
Here is the code I tried:
fig=plt.figure(constrained_layout=True,figsize=(20,20))
#fig.tight_layout(rect=[0, 0, 1, 0])
fig.suptitle('Embark ratio for each Social class',fontsize=30)
axes=fig.subplot_mosaic([
['A','B','C']
])
axes['A'].set_title('1st Class',fontsize=20)
axes['B'].set_title('2nd Class',fontsize=20)
axes['C'].set_title('3rd Class',fontsize=20)
data[data['Pclass']==1]['Embarked'].value_counts().plot.pie(autopct='%1.1f%%',pctdistance=0.8,ax=axes['A'],textprops={'fontsize':20})
data[data['Pclass']==2]['Embarked'].value_counts().plot.pie(autopct='%1.1f%%',pctdistance=0.75,ax=axes['B'],textprops={'fontsize':20})
data[data['Pclass']==3]['Embarked'].value_counts().plot.pie(autopct='%1.1f%%',pctdistance=0.5,ax=axes['C'],textprops={'fontsize':20})
plt.show()

Related

Matplotlib: plot variable number of subplots over a color gradient

I'm trying to make a plot with multiple violin plots on one axis. The amount of violin plots is variable, and I would like to make plot 1 a very light blue, plot 2 a little darker blue, all the way to the last plot, which I would like to be black. So depending on the amount of plots, the steps in the color gradient should be higher or lower. Is there a (simple) way to do this with matplotlib itself (i.e. no extra module)? I referenced matplotlib's documentation on color maps, but this did not bring me much further. Anyone who could help? Thanks in advance!
# Current code:
for i, l in enumerate(self.H):
vplot = ax3.violinplot(
l, positions=[i + 1], widths=0.5, showmeans=True, showmedians=False)
for pc in vplot['bodies']:
pc.set_facecolor(colors[i])
pc.set_label(labels[i])

Why are matplotlib subplots so far away from eachother?

So in general when I'm doing subplots of multiple rows, the result appears ugly : the distance between each row is much bigger than the distance between each column
Here is an example in which i'm showing on a 2*4 subplot grid the same image contained in Y[...,0]
import matplotlib.pyplot as plt
plt.figure(figsize=(10,10))
for i in range(8):
plt.subplot(2,4,i+1)
plt.imshow(Y[...,0])
plt.show()
Screenshot of the result. As you can see, there is a big white space between the two rows.
Is there a way to fix that ?

matplotlib // space between subplots

I want to plot images (in the 1st row) along with some diagrams (the 2nd and 3rd rows) using subplots from matplotlib.pyplot. However, imshow fucntion adds some additional white space around images I can't get rid of. Here is my code and the plot I'm getting:
rcParams['figure.figsize'] = (16, 14)
_, axes = plt.subplots(3, 3)
axes[0][0].imshow(image)
axes[0][0].set_title('title')
axes[0][0].set_xticklabels(list())
axes[0][0].set_yticklabels(list())
axes[0][0].grid(False)
axes[0][1].imshow(image)
axes[0][1].set_title('title')
axes[0][1].set_xticklabels(list())
axes[0][1].set_yticklabels(list())
axes[0][1].grid(False)
axes[0][2].imshow(image)
axes[0][2].set_title('title')
axes[0][2].set_xticklabels(list())
axes[0][2].set_yticklabels(list())
axes[0][2].grid(False)
plt.savefig(file_name, bbox_inches='tight')
in the plot below you can clearly see that there is significantly more space between the 1st and 2nd rows:
I would like to have an equal space between all subplots. What would be the easiest way to do this?
Thanks in advance for any advice!
Best,
Alexey
This is because imshow is showing the image with square pixels. If the image as a ratio of e.g. 16:9, the subplot will be reshaped to fit the image size. They will therefore have a different shape from the other subplots (see the imshow documentation for more info).
From here, you have two solutions:
decrease the figure height in order to reduce manually the vertical space between subplots
prevent imshow to resize the axes based on the images. For this you can set the aspect ratio to automatic aspect="auto", and the image will fit the existing axes

Matplotlib - saving an image without any whitespace nor gridlines visible

I have some really simple figures that I'm trying to generate for an experiment. They're just supposed to be bars with 3 colors, each color representing a different probability for an event.
I approached this by creating a horizontal stacked barplot in matplotlib, then I tried removing the gridlines and margins and everything extra just so that I could see only the bars. The following
df = pd.DataFrame({"Risk":[95], "No Effect" : [3], "Gain":[2]})
df.plot(kind='barh', legend = False, stacked=True, color=['#FFFF00', '#808080', '#4169e1'])
plt.axis('off')
plt.margins(x=0)
plt.margins(y=0)
plt.grid(b=None)
plt.savefig('static/images/debug3red.png', bbox_inches='tight', pad_inches=-1)
plt.show()
This code snippet is basically what I compiled from reviewing a bunch of posts about people trying to accomplish the same task.
It's almost up to par.
Here's the image I get from plt.show(). There are still margins present, but this technically shouldn't be a problem because my savefig() call ideally should have the correct parameters to remove those margins.
Now here's the image that's saved from the savefig() call.
The image is slightly zoomed in on, and cropped partially. You can't tell that the image has been zoomed in slightly from this image, there are other instances that I've seen that better showcase that property. But you can clearly see that the image is being cropped. There are no margins at least, but...
I'm close, but what's going wrong here and how can I actually accomplish my goal?
Edit: Also for those who might be wondering (because I've heard that "pad_inches=-1" isn't elegant)...
pad_inches = 0 produces the following (for a different set of probabilities)
Edit: Based off of this answer, Removing white space around a saved image in matplotlib
The following code removes the vertical margins, but doesn't remove the horizontal margins.
plt.gca().set_axis_off()
plt.subplots_adjust(top = 1, bottom = 0, right = 1, left = 0,
hspace = 0, wspace = 0)
plt.margins(0,0)
plt.savefig('static/images/debug5.png', bbox_inches='tight', pad_inches=0.0)
Resulting in...

L-shaped Gridspec using matplotlib gs.update

This one is a quick and easy one for the matplotlib community. I was looking to plot an L-shaped gridspec layout, which I have done:
Ignoring a few layout issues I have for the moment, what I have is that the x-axis in the gs[0] plot (top left) shares the x-axis with the gs[2] plot (bottom left) and the gs[2] shares its y axis with the gs[3] plot. Now, what I was hoping to do was update the w-space and h-space to be tighter. So that the axes are almost touching, so perhaps wspace=0.02, hspace=0.02 or something similar.
I was also hoping that the bottom right hand plot was to be longer in the horizontal orientation, keeping the two left hand plots square in shape. Or as close to square as possible. If someone could run through all of the parameters I would be very appreciative. I can tinker then in my own time.
To change the spacings of the plot with grid spec:
gs = gridspec.GridSpec(2, 2,width_ratios=[1,1.5],height_ratios=[1,1])
This changes the relative size of plot gs[0] and gs[2] to gs1 and gs[3], whereas something like:
gs = gridspec.GridSpec(2, 2,width_ratios=[1,1],height_ratios=[1,2])
will change the relative sizes of plot gs[0] and gs1 to gs[2] and gs[3].
The following will tighten up the plots:
gs.update(hspace=0.01, wspace=0.01)
This gave me the following plot:
I also used the following to remove the axis labels where needed:
nullfmt = plt.NullFormatter()
ax.yaxis.set_major_formatter(nullfmt)
ax.xaxis.set_major_formatter(nullfmt)

Categories

Resources