How do I increase the figure size for this figure?
This does nothing:
fig.figsize(15, 15)
Use this on a figure object:
fig.set_figheight(15)
fig.set_figwidth(15)
Alternatively, when using .subplots() to create a new figure, specify figsize=:
fig, axs = plt.subplots(2, 2, figsize=(15, 15))
In addition to the previous answers, here is an option to set the size of the figure and the size of the subplots within the figure individually by means of gridspec_kw:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
#generate random data
x,y=range(100), range(10)
z=np.random.random((len(x),len(y)))
Y=[z[i].sum() for i in range(len(x))]
z=pd.DataFrame(z).unstack().reset_index()
#Plot data
fig, axs = plt.subplots(2,1,figsize=(16,9), gridspec_kw={'height_ratios': [1, 2]})
axs[0].plot(Y)
axs[1].scatter(z['level_1'], z['level_0'],c=z[0])
with this figure as result:
Alternatively, create a figure() object using the figsize argument and then use add_subplot to add your subplots. E.g.
import matplotlib.pyplot as plt
import numpy as np
f = plt.figure(figsize=(10,3))
ax = f.add_subplot(121)
ax2 = f.add_subplot(122)
x = np.linspace(0,4,1000)
ax.plot(x, np.sin(x))
ax2.plot(x, np.cos(x), 'r:')
Benefits of this method are that the syntax is closer to calls of subplot() instead of subplots(). E.g. subplots doesn't seem to support using a GridSpec for controlling the spacing of the subplots, but both subplot() and add_subplot() do.
You can use plt.figure(figsize = (16,8)) to change figure size of a single plot and with up to two subplots. (arguments inside figsize lets to modify the figure size)
To change figure size of more subplots you can use plt.subplots(2,2,figsize=(10,10)) when creating subplots.
from matplotlib import pyplot as plt
lis=[img,gaussian_img,gaussian_img_8bit]
f,axs=plt.subplots(3,1,figsize=(25,25)) #ROW,COLUMN
axs[0].imshow(lis[0])
axs[1].imshow(lis[1])
axs[2].imshow(lis[2])
For plotting subplots in a for loop which is useful sometimes:
Sample code to for a matplotlib plot of multiple subplots of histograms from a multivariate numpy array (2 dimensional).
plt.figure(figsize=(16, 8))
for i in range(1, 7):
plt.subplot(2, 3, i)
plt.title('Histogram of {}'.format(str(i)))
plt.hist(x[:,i-1], bins=60)
Related
The code below produces gaps between the subplots. How do I remove the gaps between the subplots and make the image a tight grid?
import matplotlib.pyplot as plt
for i in range(16):
i = i + 1
ax1 = plt.subplot(4, 4, i)
plt.axis('on')
ax1.set_xticklabels([])
ax1.set_yticklabels([])
ax1.set_aspect('equal')
plt.subplots_adjust(wspace=None, hspace=None)
plt.show()
The problem is the use of aspect='equal', which prevents the subplots from stretching to an arbitrary aspect ratio and filling up all the empty space.
Normally, this would work:
import matplotlib.pyplot as plt
ax = [plt.subplot(2,2,i+1) for i in range(4)]
for a in ax:
a.set_xticklabels([])
a.set_yticklabels([])
plt.subplots_adjust(wspace=0, hspace=0)
The result is this:
However, with aspect='equal', as in the following code:
import matplotlib.pyplot as plt
ax = [plt.subplot(2,2,i+1) for i in range(4)]
for a in ax:
a.set_xticklabels([])
a.set_yticklabels([])
a.set_aspect('equal')
plt.subplots_adjust(wspace=0, hspace=0)
This is what we get:
The difference in this second case is that you've forced the x- and y-axes to have the same number of units/pixel. Since the axes go from 0 to 1 by default (i.e., before you plot anything), using aspect='equal' forces each axis to be a square. Since the figure is not a square, pyplot adds in extra spacing between the axes horizontally.
To get around this problem, you can set your figure to have the correct aspect ratio. We're going to use the object-oriented pyplot interface here, which I consider to be superior in general:
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(8,8)) # Notice the equal aspect ratio
ax = [fig.add_subplot(2,2,i+1) for i in range(4)]
for a in ax:
a.set_xticklabels([])
a.set_yticklabels([])
a.set_aspect('equal')
fig.subplots_adjust(wspace=0, hspace=0)
Here's the result:
You can use gridspec to control the spacing between axes. There's more information here.
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
plt.figure(figsize = (4,4))
gs1 = gridspec.GridSpec(4, 4)
gs1.update(wspace=0.025, hspace=0.05) # set the spacing between axes.
for i in range(16):
# i = i + 1 # grid spec indexes from 0
ax1 = plt.subplot(gs1[i])
plt.axis('on')
ax1.set_xticklabels([])
ax1.set_yticklabels([])
ax1.set_aspect('equal')
plt.show()
Without resorting gridspec entirely, the following might also be used to remove the gaps by setting wspace and hspace to zero:
import matplotlib.pyplot as plt
plt.clf()
f, axarr = plt.subplots(4, 4, gridspec_kw = {'wspace':0, 'hspace':0})
for i, ax in enumerate(f.axes):
ax.grid('on', linestyle='--')
ax.set_xticklabels([])
ax.set_yticklabels([])
plt.show()
plt.close()
Resulting in:
With recent matplotlib versions you might want to try Constrained Layout. This does (or at least did) not work with plt.subplot() however, so you need to use plt.subplots() instead:
fig, axs = plt.subplots(4, 4, constrained_layout=True)
Have you tried plt.tight_layout()?
with plt.tight_layout()
without it:
Or: something like this (use add_axes)
left=[0.1,0.3,0.5,0.7]
width=[0.2,0.2, 0.2, 0.2]
rectLS=[]
for x in left:
for y in left:
rectLS.append([x, y, 0.2, 0.2])
axLS=[]
fig=plt.figure()
axLS.append(fig.add_axes(rectLS[0]))
for i in [1,2,3]:
axLS.append(fig.add_axes(rectLS[i],sharey=axLS[-1]))
axLS.append(fig.add_axes(rectLS[4]))
for i in [1,2,3]:
axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))
axLS.append(fig.add_axes(rectLS[8]))
for i in [5,6,7]:
axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))
axLS.append(fig.add_axes(rectLS[12]))
for i in [9,10,11]:
axLS.append(fig.add_axes(rectLS[i+4],sharex=axLS[i],sharey=axLS[-1]))
If you don't need to share axes, then simply axLS=map(fig.add_axes, rectLS)
Another method is to use the pad keyword from plt.subplots_adjust(), which also accepts negative values:
import matplotlib.pyplot as plt
ax = [plt.subplot(2,2,i+1) for i in range(4)]
for a in ax:
a.set_xticklabels([])
a.set_yticklabels([])
plt.subplots_adjust(pad=-5.0)
Additionally, to remove the white at the outer fringe of all subplots (i.e. the canvas), always save with plt.savefig(fname, bbox_inches="tight").
I am doing a plot something like this:
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
fig = plt.gcf()
ax = plt.gca()
ax.pcolormesh(np.random.rand(10, 10))
fig.colorbar(mpl.cm.ScalarMappable(), ax=ax)
The last line adds a colorbar and a second axis
fig.axes
>>> [<AxesSubplot:>, <AxesSubplot:label='<colorbar>'>]
My question:
Is there any relation between the two axes that can be used to get the axis of the colorbar (second in the list above) using only the axis returned by ax = plt.gca() (first returned in the list above)?
As far as I know, if you define pcolormesh and colorbar that way, no.
Anyway, you can define an ax for the pcolormesh and a cax for the colorbar beforehand. Then you can pass cax as parameter to matplotlib.pyplot.colorbar. In this way you can access to both axis ax and cax as you need.
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
grid_kws = {'width_ratios': (0.9, 0.05), 'wspace': 0.2}
fig, (ax, cax) = plt.subplots(1, 2, gridspec_kw = grid_kws, figsize = (10, 8))
ax.pcolormesh(np.random.rand(10, 10))
plt.colorbar(mpl.cm.ScalarMappable(), cax=cax)
plt.show()
In general, focusing on your code:
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
fig = plt.gcf()
ax = plt.gca()
ax.pcolormesh(np.random.rand(10, 10))
fig.colorbar(mpl.cm.ScalarMappable(), ax=ax)
starting from ax, you can get its figure with ax.figure. From there, you can get the list of all figure axes with ax.figure.axes. So, if you want to get colobar's axis using only pcolormesh' axis, you should use:
ax.figure.axes[1]
The parent figure, as far as I know, is the only relation between the two axes.
How do I increase the figure size for this figure?
This does nothing:
fig.figsize(15, 15)
Use this on a figure object:
fig.set_figheight(15)
fig.set_figwidth(15)
Alternatively, when using .subplots() to create a new figure, specify figsize=:
fig, axs = plt.subplots(2, 2, figsize=(15, 15))
In addition to the previous answers, here is an option to set the size of the figure and the size of the subplots within the figure individually by means of gridspec_kw:
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
#generate random data
x,y=range(100), range(10)
z=np.random.random((len(x),len(y)))
Y=[z[i].sum() for i in range(len(x))]
z=pd.DataFrame(z).unstack().reset_index()
#Plot data
fig, axs = plt.subplots(2,1,figsize=(16,9), gridspec_kw={'height_ratios': [1, 2]})
axs[0].plot(Y)
axs[1].scatter(z['level_1'], z['level_0'],c=z[0])
with this figure as result:
Alternatively, create a figure() object using the figsize argument and then use add_subplot to add your subplots. E.g.
import matplotlib.pyplot as plt
import numpy as np
f = plt.figure(figsize=(10,3))
ax = f.add_subplot(121)
ax2 = f.add_subplot(122)
x = np.linspace(0,4,1000)
ax.plot(x, np.sin(x))
ax2.plot(x, np.cos(x), 'r:')
Benefits of this method are that the syntax is closer to calls of subplot() instead of subplots(). E.g. subplots doesn't seem to support using a GridSpec for controlling the spacing of the subplots, but both subplot() and add_subplot() do.
You can use plt.figure(figsize = (16,8)) to change figure size of a single plot and with up to two subplots. (arguments inside figsize lets to modify the figure size)
To change figure size of more subplots you can use plt.subplots(2,2,figsize=(10,10)) when creating subplots.
from matplotlib import pyplot as plt
lis=[img,gaussian_img,gaussian_img_8bit]
f,axs=plt.subplots(3,1,figsize=(25,25)) #ROW,COLUMN
axs[0].imshow(lis[0])
axs[1].imshow(lis[1])
axs[2].imshow(lis[2])
For plotting subplots in a for loop which is useful sometimes:
Sample code to for a matplotlib plot of multiple subplots of histograms from a multivariate numpy array (2 dimensional).
plt.figure(figsize=(16, 8))
for i in range(1, 7):
plt.subplot(2, 3, i)
plt.title('Histogram of {}'.format(str(i)))
plt.hist(x[:,i-1], bins=60)
I want to add grid graph as a background of a signal plot generated from the following code?
dff = pd.read_csv("abc.csv")
x = dff['A']
times = np.arange(len(x))/360
plt.subplot(121)
plt.plot(times, x)
plt.tight_layout()
plt.show()
What should I change in this code. Can anyone help me out.Thanks in advance!
To add gridlines to PyPlot plots, you can use the grid() tool:
import matplotlib.pyplot as plt
plt.subplot(121)
plt.plot()
plt.tight_layout()
plt.grid(axis='both')
plt.show()
You can see more about its arguments here.
Note that in matplotlib you might have a better time using figures with the "axes" object, rather than the functional interface. E.g.:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
ax.plot()
ax.grid()
This allows you to index axs objects like lists, and pass plots as arguments.
I am having a big plot where I initiated with:
import numpy as np
import matplotlib.pyplot as plt
fig, axs = plt.subplots(5, 4)
And I want to do share-x-axis between column 1 and 2; and do the same between column 3 and 4. However, column 1 and 2 does not share the same axis with column 3 and 4.
I was wondering that would there be anyway to do this, and not sharex=True and sharey=True across all figures?
PS: This tutorial does not help too much, because it is only about sharing x/y within each row/column; they cannot do axis sharing between different rows/columns (unless share them across all axes).
I'm not exactly sure what you want to achieve from your question. However, you can specify per subplot which axis it should share with which subplot when adding a subplot to your figure.
This can be done via:
import matplotlib.pylab as plt
fig = plt.figure()
ax1 = fig.add_subplot(5, 4, 1)
ax2 = fig.add_subplot(5, 4, 2, sharex = ax1)
ax3 = fig.add_subplot(5, 4, 3, sharex = ax1, sharey = ax1)
A slightly limited but much simpler option is available for subplots. The limitation is there for a complete row or column of subplots.
For example, if one wants to have common y axis for all the subplots but common x axis only for individual columns in a 3x2 subplot, one could specify it as:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(3, 2, sharey=True, sharex='col')
One can manually manage axes sharing using a Grouper object, which can be accessed via ax._shared_x_axes and ax._shared_y_axes. For example,
import matplotlib.pyplot as plt
def set_share_axes(axs, target=None, sharex=False, sharey=False):
if target is None:
target = axs.flat[0]
# Manage share using grouper objects
for ax in axs.flat:
if sharex:
target._shared_x_axes.join(target, ax)
if sharey:
target._shared_y_axes.join(target, ax)
# Turn off x tick labels and offset text for all but the bottom row
if sharex and axs.ndim > 1:
for ax in axs[:-1,:].flat:
ax.xaxis.set_tick_params(which='both', labelbottom=False, labeltop=False)
ax.xaxis.offsetText.set_visible(False)
# Turn off y tick labels and offset text for all but the left most column
if sharey and axs.ndim > 1:
for ax in axs[:,1:].flat:
ax.yaxis.set_tick_params(which='both', labelleft=False, labelright=False)
ax.yaxis.offsetText.set_visible(False)
fig, axs = plt.subplots(5, 4)
set_share_axes(axs[:,:2], sharex=True)
set_share_axes(axs[:,2:], sharex=True)
To adjust the spacing between subplots in a grouped manner, please refer to this question.
I used Axes.sharex /sharey in a similar setting
https://matplotlib.org/stable/api/_as_gen/matplotlib.axes.Axes.sharex.html#matplotlib.axes.Axes.sharex
import matplotlib.pyplot as plt
fig, axd = plt.subplot_mosaic([list(range(3))] +[['A']*3, ['B']*3])
axd[0].plot([0,0.2])
axd['A'].plot([1,2,3])
axd['B'].plot([1,2,3,4,5])
axd['B'].sharex(axd['A'])
for i in [1,2]:
axd[i].sharey(axd[0])
plt.show()