I have a code that plots multiple plots - a heatmap and a barplot in a single plot in Seaborn. However, both plots are sized equally, i.e, one half of overall figure is heatmap, other half is barplot. Is there a way to control individual plot sizes such that heatmap occupies 75% of the plot size while barplot occupies only 25% of the plot?
Reference Code:
ig, ax = plt.subplots(1, 2, figsize=(7, 5))
heatmap = np.random.uniform(0, 1, size=(12, 12))
sns.heatmap(heatmap_scores, linewidth=0.5, cmap="OrRd", ax=ax[0])
ax[0].set_xlabel('Head')
ax[0].set_ylabel('Layer')
ax[0].set_title('Attention Heatmap')
x = np.mean(heatmap_scores, axis=1)
y = np.arange(0, 12)
sns.barplot(x=x, y=y, ax=ax[1], orient='h', color='r', dodge=False)
ax[1].set_title('Layer Average')
ax[1].set(yticklabels=[])
plt.savefig('fig.png')
plt.close()
You can customize GridSpec options, passing them to subplots, with the key gridspec_kw:
fig, ax = plt.subplots(1, 2, figsize=(7, 5), gridspec_kw={'width_ratios': [.75, .25]})
I have the following Matplotlib figure, with 2 charts:
That i created with the following code:
fig = plt.figure(facecolor='#131722',dpi=155, figsize=(8, 4))
ax1 = plt.subplot2grid((1,2), (0,0), facecolor='#131722')
ax2 = plt.subplot2grid((1,2), (0,1), facecolor='#131722')
Now i would like to add two charts, so ax3 and ax4, each needs to be below the two charts, they should have the same width of the two charts but half the height of the two bigger charts. How can i do that? I tried various solutions from here here but i'm struggling to get the expected output
You can achieve this using the gridspec_kw argument of plt.subplots. This allows you to specify the dimensions of the grid (in this case 2x2) and the ratio of the heights:
f, ax = plt.subplots(2, 2 , gridspec_kw={"height_ratios": [2, 1]})
for cAx in ax.flatten():
cAx.set_facecolor('#131722')
f.savefig("test.png", facecolor='#131722')
Alternatively, you can also create a 3x2 grid and specify that the first two subplots need to span two rows:
fig = plt.figure(facecolor='#131722',dpi=155, figsize=(8, 6))
ax1 = plt.subplot2grid((3,2), (0,0), facecolor='#131722', rowspan=2)
ax2 = plt.subplot2grid((3,2), (0,1), facecolor='#131722', rowspan=2)
ax3 = plt.subplot2grid((3,2), (2,0), facecolor='#131722')
ax4 = plt.subplot2grid((3,2), (2,1), facecolor='#131722')
I would like to arrange four Seaborn plots in a 2 x 2 grid. I tried the following code but I got an exception. I would also like to know how to set titles and xlabel, ylabel in the subplots and a title for the overall grid plot.
Some toy data:
df
'{"age":{"76":33,"190":30,"255":36,"296":27,"222":19,"147":39,"127":23,"98":24,"168":29,"177":39,"197":27,"131":36,"36":30,"219":28,"108":38,"198":34,"40":32,"246":24,"109":26,"117":47,"20":26,"113":24,"279":35,"120":35,"7":26,"119":28,"272":24,"66":28,"87":28,"133":28},"Less_than_College":{"76":1,"190":1,"255":0,"296":1,"222":1,"147":1,"127":0,"98":0,"168":1,"177":1,"197":0,"131":1,"36":0,"219":0,"108":0,"198":0,"40":0,"246":0,"109":1,"117":1,"20":0,"113":0,"279":0,"120":0,"7":0,"119":1,"272":0,"66":1,"87":0,"133":0},"college":{"76":0,"190":0,"255":0,"296":0,"222":0,"147":0,"127":1,"98":1,"168":0,"177":0,"197":1,"131":0,"36":1,"219":1,"108":0,"198":1,"40":1,"246":0,"109":0,"117":0,"20":1,"113":1,"279":0,"120":1,"7":1,"119":0,"272":0,"66":0,"87":1,"133":1},"Bachelor":{"76":0,"190":0,"255":1,"296":0,"222":0,"147":0,"127":0,"98":0,"168":0,"177":0,"197":0,"131":0,"36":0,"219":0,"108":1,"198":0,"40":0,"246":1,"109":0,"117":0,"20":0,"113":0,"279":1,"120":0,"7":0,"119":0,"272":1,"66":0,"87":0,"133":0},"terms":{"76":30,"190":15,"255":30,"296":30,"222":30,"147":15,"127":15,"98":15,"168":30,"177":30,"197":15,"131":30,"36":15,"219":15,"108":30,"198":7,"40":30,"246":15,"109":15,"117":15,"20":15,"113":15,"279":15,"120":15,"7":15,"119":30,"272":15,"66":30,"87":30,"133":15},"Principal":{"76":1000,"190":1000,"255":1000,"296":1000,"222":1000,"147":800,"127":800,"98":800,"168":1000,"177":1000,"197":1000,"131":1000,"36":1000,"219":800,"108":1000,"198":1000,"40":1000,"246":1000,"109":1000,"117":1000,"20":1000,"113":800,"279":800,"120":800,"7":800,"119":1000,"272":1000,"66":1000,"87":1000,"133":1000}}'
fig = plt.figure()
fig.subplots_adjust(hspace=0.4, wspace=0.4)
ax = fig.add_subplot(2, 2, 1)
ax.sns.distplot(df.Principal)
ax = fig.add_subplot(2, 2, 2)
ax.sns.distplot(df.terms)
ax = fig.add_subplot(2, 2, 3)
ax.sns.barplot(data = df[['Less_than_College', 'college', 'Bachelor', ]])
ax = fig.add_subplot(2, 2, 4)
ax.sns.boxplot(data = df['age'])
plt.show()
AttributeError: 'AxesSubplot' object has no attribute 'sns'
ax is matplotlib object that do not have sns attribute, because of this you are getting error. sns is seaborn object. If you want to use ax object with seaborn plot for your case pass parameter ax=ax in seaborn object as follows:
fig = plt.figure()
fig.subplots_adjust(hspace=0.4, wspace=0.4)
ax = fig.add_subplot(2, 2, 1)
sns.distplot(df.Principal,ax=ax)
ax = fig.add_subplot(2, 2, 2)
sns.distplot(df.terms,ax=ax)
ax = fig.add_subplot(2, 2, 3)
sns.barplot(data = df[['Less_than_College', 'college', 'Bachelor']],ax=ax)
ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
ax = fig.add_subplot(2, 2, 4)
sns.boxplot(df['age'],ax=ax)
plt.show()
The plot looks like this.