How to adjust the plot size in Matplotlib? - python

I'm trying to remove the white space from the plot that I created:
As it is possible to see, there a big white spot on the right and also on the bottom, how to fix it? Here is my script:
fig = plt.figure(figsize=(7,7))
ax1 = plt.subplot2grid((4,3), (0,0),)
ax2 = plt.subplot2grid((4,3), (1,0),)
ax3 = plt.subplot2grid((4,3), (0,1),)
ax4 = plt.subplot2grid((4,3), (1,1),)
data = self.dframe[i]
tes = print_data(data, self.issues, self.color, self.type_user)
tes.print_top(data=data, top=10, ax=ax1, typegraph="hbar", problem=self.issues[i], tone=self.color[i])
tes.print_top(data=data, top=10, ax=ax2, typegraph="prod_bar", problem=self.issues[i], tone=self.color[i])
tes.print_top(data=data, top=10, ax=ax3, typegraph="reg_hbar", problem=self.issues[i], tone=self.color[i])
tes.print_top(data=data, top=10, ax=ax4, typegraph=self.type_user, problem=self.issues[i], tone=self.color[i])
problem = self.issues[i]
plt.tight_layout()
name = problem + str('.PNG')
plt.close(fig)
fig.savefig(name)

You are creating too many subplots!
If we look at this line:
ax1 = plt.subplot2grid((4,3), (0,0),)
We can see the first argument given to subplot2grid are the dimensions of the subplot grid to be made, in this case 4 rows, and 3 columns. You are then plotting in the subplots in the top left of your figure (the second argument given) which leaves a lot of space that's not used.
So to solve this, reduce the number of subplots by using:
ax1 = plt.subplot2grid((2,2), (0,0),)
Full example:
import numpy as np
import matplotlib.pyplot as plt
data = np.random.randn(25)
fig = plt.figure(figsize=(7,7))
ax1 = plt.subplot2grid((2,2), (0,0),)
ax2 = plt.subplot2grid((2,2), (1,0),)
ax3 = plt.subplot2grid((2,2), (0,1),)
ax4 = plt.subplot2grid((2,2), (1,1),)
ax1.plot(data)
ax2.plot(data)
ax3.plot(data)
ax4.plot(data)
plt.show()
Giving:

you can use
plt.subplots_adjust(left=0.09, bottom=0.07, right=0.98, top=0.97, wspace=0.2 , hspace=0.17 ) to adjust the window.
But the issue is that a lot of the space in your plot is empty
maybe you should change
plt.subplot2grid((4,3)... to plt.subplot2grid((2,2)

Related

Why can't I change the padding on my GridSpecFromSubplotSpec? [duplicate]

I would like to make a variable (two different) wspace using GridSpec in matplotlib.
I would like to achieve the following:
I'm using the following so far:
gs1 = gridspec.GridSpec(6, 3, width_ratios=[1.5,1,1])
gs1.update(wspace=0.4, hspace=0.3)
ax1 = fig.add_subplot(gs1[0:2,0])
ax2 = fig.add_subplot(gs1[2:4,0])
ax3 = fig.add_subplot(gs1[4:6,0])
ax4 = fig.add_subplot(gs1[0:3,1])
ax5 = fig.add_subplot(gs1[3:6,1])
ax6 = fig.add_subplot(gs1[0:3,2])
ax7 = fig.add_subplot(gs1[3:6,2])
Any idea how to obtain the two different space highlighted in green in my amazing hand drawing ?
Thanks a lot !
Sam
You may use 2 GridSpecs, one which contains one column and 3 rows and one which contains two rows and two colums. You can then let the first extend only to less than half of the figure and start the second at half the figure width. The difference between the left and right parameter will be the spacing.
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
fig = plt.figure()
gs1 = GridSpec(3, 1, right=0.4)
gs2 = GridSpec(2, 2, left=0.5)
ax1 = fig.add_subplot(gs1[0,0])
ax2 = fig.add_subplot(gs1[1,0])
ax3 = fig.add_subplot(gs1[2,0])
ax4 = fig.add_subplot(gs2[0,0])
ax5 = fig.add_subplot(gs2[0,1])
ax6 = fig.add_subplot(gs2[1,0])
ax7 = fig.add_subplot(gs2[1,1])
plt.show()
The same can be achieved with first defining an "outer" gridspec with two columns and placing an inner gridspec into each of them.
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec, GridSpecFromSubplotSpec
fig = plt.figure()
gs = GridSpec(1, 2, width_ratios=[1.5,2], wspace=0.3)
gs1 = GridSpecFromSubplotSpec(3, 1, subplot_spec=gs[0])
gs2 = GridSpecFromSubplotSpec(2, 2, subplot_spec=gs[1])
ax1 = fig.add_subplot(gs1[0,0])
ax2 = fig.add_subplot(gs1[1,0])
ax3 = fig.add_subplot(gs1[2,0])
ax4 = fig.add_subplot(gs2[0,0])
ax5 = fig.add_subplot(gs2[0,1])
ax6 = fig.add_subplot(gs2[1,0])
ax7 = fig.add_subplot(gs2[1,1])
plt.show()

Variable wspace with gridspec.GridSpec in python

I would like to make a variable (two different) wspace using GridSpec in matplotlib.
I would like to achieve the following:
I'm using the following so far:
gs1 = gridspec.GridSpec(6, 3, width_ratios=[1.5,1,1])
gs1.update(wspace=0.4, hspace=0.3)
ax1 = fig.add_subplot(gs1[0:2,0])
ax2 = fig.add_subplot(gs1[2:4,0])
ax3 = fig.add_subplot(gs1[4:6,0])
ax4 = fig.add_subplot(gs1[0:3,1])
ax5 = fig.add_subplot(gs1[3:6,1])
ax6 = fig.add_subplot(gs1[0:3,2])
ax7 = fig.add_subplot(gs1[3:6,2])
Any idea how to obtain the two different space highlighted in green in my amazing hand drawing ?
Thanks a lot !
Sam
You may use 2 GridSpecs, one which contains one column and 3 rows and one which contains two rows and two colums. You can then let the first extend only to less than half of the figure and start the second at half the figure width. The difference between the left and right parameter will be the spacing.
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec
fig = plt.figure()
gs1 = GridSpec(3, 1, right=0.4)
gs2 = GridSpec(2, 2, left=0.5)
ax1 = fig.add_subplot(gs1[0,0])
ax2 = fig.add_subplot(gs1[1,0])
ax3 = fig.add_subplot(gs1[2,0])
ax4 = fig.add_subplot(gs2[0,0])
ax5 = fig.add_subplot(gs2[0,1])
ax6 = fig.add_subplot(gs2[1,0])
ax7 = fig.add_subplot(gs2[1,1])
plt.show()
The same can be achieved with first defining an "outer" gridspec with two columns and placing an inner gridspec into each of them.
import matplotlib.pyplot as plt
from matplotlib.gridspec import GridSpec, GridSpecFromSubplotSpec
fig = plt.figure()
gs = GridSpec(1, 2, width_ratios=[1.5,2], wspace=0.3)
gs1 = GridSpecFromSubplotSpec(3, 1, subplot_spec=gs[0])
gs2 = GridSpecFromSubplotSpec(2, 2, subplot_spec=gs[1])
ax1 = fig.add_subplot(gs1[0,0])
ax2 = fig.add_subplot(gs1[1,0])
ax3 = fig.add_subplot(gs1[2,0])
ax4 = fig.add_subplot(gs2[0,0])
ax5 = fig.add_subplot(gs2[0,1])
ax6 = fig.add_subplot(gs2[1,0])
ax7 = fig.add_subplot(gs2[1,1])
plt.show()

Dynamic Subplots in Matplotlib GUI [duplicate]

I've got a figure that contains three subplots which are arranged vertically. Once I click into the figure, I want the second subplot ax2 to be hidden and the other plots to fill the space. A second click into the figure should restore the original plot and layout.
Hiding the subplot ax2 isn't a problem, but how can I rearrange the positions of the other subplots?
I've tried creating a new GridSpec, using the set_position and set_subplotspec methods, but nothing worked out. I'm sure I'm missing something here, any help would be appreciated.
This is my code:
import matplotlib.pyplot as plt
from matplotlib import gridspec
fig = plt.figure()
gs = gridspec.GridSpec(3, 1, height_ratios=[5, 2, 1])
ax1 = fig.add_subplot(gs[0])
ax2 = fig.add_subplot(gs[1], sharex=ax1)
ax3 = fig.add_subplot(gs[2], sharex=ax2)
visible = True
def toggle_ax2(event):
global visible
visible = not visible
ax2.set_visible(visible)
plt.draw()
fig.canvas.mpl_connect('button_press_event', toggle_ax2)
plt.show()
You can define two different GridSpecs. One would have 3 subplots, the other 2. Depending on the visibility of the middle axes, you change the position of the other two axes to obey to the first or second GridSpec.
(There is no need for any dummy figure or so, like other answers might suggest.)
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
fig = plt.figure()
gs = gridspec.GridSpec(3, 1, height_ratios=[5, 2, 1], hspace=0.3)
gs2 = gridspec.GridSpec(2,1, height_ratios=[5,3])
ax1 = fig.add_subplot(gs[0])
ax2 = fig.add_subplot(gs[1], sharex=ax1)
ax3 = fig.add_subplot(gs[2], sharex=ax2)
ax1.plot([1,2,3], [1,2,3], color="crimson")
ax2.plot([1,2,3], [2,3,1], color="darkorange")
ax3.plot([1,2,3], [3,2,1], color="limegreen")
visible = True
def toggle_ax2(event):
global visible
visible = not visible
ax2.set_visible(visible)
if visible:
ax1.set_position(gs[0].get_position(fig))
ax3.set_position(gs[2].get_position(fig))
else:
ax1.set_position(gs2[0].get_position(fig))
ax3.set_position(gs2[1].get_position(fig))
plt.draw()
fig.canvas.mpl_connect('button_press_event', toggle_ax2)
plt.show()
Left: original; right: after clicking
You can create a new gridspec instance, and use that to create some dummy figures in a second figure (you can close this before you plt.show, so you never actually see it, we just want to grab some positions from the axes here).
By storing the two possible positions for ax1 and ax3 from that dummy figure and the original figure, then you can use ax.set_position() in your toggle_ax2 function to change the positions of the remaining two axes.
import matplotlib.pyplot as plt
from matplotlib import gridspec
fig = plt.figure()
gs = gridspec.GridSpec(3, 1, height_ratios=[5, 2, 1])
ax1 = fig.add_subplot(gs[0])
ax2 = fig.add_subplot(gs[1], sharex=ax1)
ax3 = fig.add_subplot(gs[2], sharex=ax2)
# Store the original positions of ax1 and ax3
pos1_1 = ax1.get_position()
pos3_1 = ax3.get_position()
# Create a second gridspec for when ax2 is hidden. Keep 5:1 ratio
gs2 = gridspec.GridSpec(2, 1, height_ratios=[5, 1])
fig2 = plt.figure()
ax1_2 = fig2.add_subplot(gs2[0])
ax3_2 = fig2.add_subplot(gs2[1])
# Store the positions of ax1 and ax3 in the new gridspec
pos1_2 = ax1_2.get_position()
pos3_2 = ax3_2.get_position()
# Close the dummy figure2
plt.close(fig2)
visible = True
def toggle_ax2(event):
global visible
visible = not visible
ax2.set_visible(visible)
# Use the stored positions to switch between
# different arrangements of ax1 and ax3
if visible:
ax1.set_position(pos1_1)
ax3.set_position(pos3_1)
else:
ax1.set_position(pos1_2)
ax3.set_position(pos3_2)
plt.draw()
fig.canvas.mpl_connect('button_press_event', toggle_ax2)
plt.show()
Original configuration:
After removing ax2:

matplotlib: hide subplot and fill space with other subplots

I've got a figure that contains three subplots which are arranged vertically. Once I click into the figure, I want the second subplot ax2 to be hidden and the other plots to fill the space. A second click into the figure should restore the original plot and layout.
Hiding the subplot ax2 isn't a problem, but how can I rearrange the positions of the other subplots?
I've tried creating a new GridSpec, using the set_position and set_subplotspec methods, but nothing worked out. I'm sure I'm missing something here, any help would be appreciated.
This is my code:
import matplotlib.pyplot as plt
from matplotlib import gridspec
fig = plt.figure()
gs = gridspec.GridSpec(3, 1, height_ratios=[5, 2, 1])
ax1 = fig.add_subplot(gs[0])
ax2 = fig.add_subplot(gs[1], sharex=ax1)
ax3 = fig.add_subplot(gs[2], sharex=ax2)
visible = True
def toggle_ax2(event):
global visible
visible = not visible
ax2.set_visible(visible)
plt.draw()
fig.canvas.mpl_connect('button_press_event', toggle_ax2)
plt.show()
You can define two different GridSpecs. One would have 3 subplots, the other 2. Depending on the visibility of the middle axes, you change the position of the other two axes to obey to the first or second GridSpec.
(There is no need for any dummy figure or so, like other answers might suggest.)
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
fig = plt.figure()
gs = gridspec.GridSpec(3, 1, height_ratios=[5, 2, 1], hspace=0.3)
gs2 = gridspec.GridSpec(2,1, height_ratios=[5,3])
ax1 = fig.add_subplot(gs[0])
ax2 = fig.add_subplot(gs[1], sharex=ax1)
ax3 = fig.add_subplot(gs[2], sharex=ax2)
ax1.plot([1,2,3], [1,2,3], color="crimson")
ax2.plot([1,2,3], [2,3,1], color="darkorange")
ax3.plot([1,2,3], [3,2,1], color="limegreen")
visible = True
def toggle_ax2(event):
global visible
visible = not visible
ax2.set_visible(visible)
if visible:
ax1.set_position(gs[0].get_position(fig))
ax3.set_position(gs[2].get_position(fig))
else:
ax1.set_position(gs2[0].get_position(fig))
ax3.set_position(gs2[1].get_position(fig))
plt.draw()
fig.canvas.mpl_connect('button_press_event', toggle_ax2)
plt.show()
Left: original; right: after clicking
You can create a new gridspec instance, and use that to create some dummy figures in a second figure (you can close this before you plt.show, so you never actually see it, we just want to grab some positions from the axes here).
By storing the two possible positions for ax1 and ax3 from that dummy figure and the original figure, then you can use ax.set_position() in your toggle_ax2 function to change the positions of the remaining two axes.
import matplotlib.pyplot as plt
from matplotlib import gridspec
fig = plt.figure()
gs = gridspec.GridSpec(3, 1, height_ratios=[5, 2, 1])
ax1 = fig.add_subplot(gs[0])
ax2 = fig.add_subplot(gs[1], sharex=ax1)
ax3 = fig.add_subplot(gs[2], sharex=ax2)
# Store the original positions of ax1 and ax3
pos1_1 = ax1.get_position()
pos3_1 = ax3.get_position()
# Create a second gridspec for when ax2 is hidden. Keep 5:1 ratio
gs2 = gridspec.GridSpec(2, 1, height_ratios=[5, 1])
fig2 = plt.figure()
ax1_2 = fig2.add_subplot(gs2[0])
ax3_2 = fig2.add_subplot(gs2[1])
# Store the positions of ax1 and ax3 in the new gridspec
pos1_2 = ax1_2.get_position()
pos3_2 = ax3_2.get_position()
# Close the dummy figure2
plt.close(fig2)
visible = True
def toggle_ax2(event):
global visible
visible = not visible
ax2.set_visible(visible)
# Use the stored positions to switch between
# different arrangements of ax1 and ax3
if visible:
ax1.set_position(pos1_1)
ax3.set_position(pos3_1)
else:
ax1.set_position(pos1_2)
ax3.set_position(pos3_2)
plt.draw()
fig.canvas.mpl_connect('button_press_event', toggle_ax2)
plt.show()
Original configuration:
After removing ax2:

Issues with python matplotlib and subplot sizes

I am trying to create a figure with 6 sub-plots in python but I am having a problem. Here is a simplified version of my code:
import matplotlib.pyplot as plt
import numpy
g_width = 200
g_height = 200
data = numpy.zeros(g_width*g_height).reshape(g_height,g_width)
ax1 = plt.subplot(231)
im1 = ax1.imshow(data)
ax2 = plt.subplot(232)
im2 = ax2.imshow(data)
ax3 = plt.subplot(233)
im3 = ax3.imshow(data)
ax0 = plt.subplot(234)
im0 = ax0.imshow(data)
ax4 = plt.subplot(235)
im4 = ax4.imshow(data)
ax5 = plt.subplot(236)
ax5.plot([1,2], [1,2])
plt.show()
The above figure has 5 "imshow-based" sub-plots and one simple-data-based sub-plot. Can someone explain to me why the box of the last sub-plot does not have the same size with the other sub-plots? If I replace the last sub-plot with an "imshow-based" sub-plot the problem disappears. Why is this happening? How can I fix it?
The aspect ratio is set to "equal" for the 5imshow()calls (check by callingax1.get_aspect()) while forax5it is set toautowhich gives you the non-square shape you observe. I'm guessingimshow()` defaults to equal while plot does not.
To fix this set all the axis aspect ratios manually e.g when creating the plot ax5 = plt.subplot(236, aspect="equal")
On a side node if your creating many axis like this you may find this useful:
fig, ax = plt.subplots(ncols=3, nrows=2, subplot_kw={'aspect':'equal'})
Then ax is a tuple (in this case ax = ((ax1, ax2, ax3), (ax4, ax5, ax6))) so to plot in the i, j plot just call
ax[i,j].plot(..)

Categories

Resources