I would like to be able to change the size of a chart in matplotlib. I have so far only been able to change the size of the window, but not the chart. I haven't been able to locate anything about this in documentation.
My Code so far:
import matplotlib.pyplot as plt
plt.rcParams['figure.figsize'] = 5,2
You don't need to modify your rcParams if you don't want to, you can pass the figsize as a keyword when you make the figure. For changing the size of the Axes (I believe that's what you mean by 'chart'), the position keyword is what you're looking for if you use add_subplot, or just the input parameter if you use add_axes. You specify it as [left, bottom, width, height]. The relevant documentation is here.
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(5,2))
ax = fig.add_subplot(111, position=[0.01, 0.01, 0.98, 0.98])
Related
I'm using
plt.legend(bbox_to_anchor = (1,1))
to put the legend outside my figure. The journal to which I'm submitting requires specific sizes for the figures. When I use this method, it increases the total width of my figure beyond the required size. I want to have the figure sized exactly to specification. Is there a way to calculate the total width of the figure including the external legend, so that I can reduce my figsize parameter accordingly?
The following works fine; I've just coloured the figure so you can see its size.
import matplotlib.pyplot as plt
import numpy as np
import matplotlib as mpl
fig, ax = plt.subplots(figsize=(3, 3), constrained_layout=True)
fig.set_facecolor('0.5')
ax.plot(np.arange(10), label='Boo')
ax.legend(bbox_to_anchor=(1, 1))
fig.savefig('boo.png')
I am trying to find an efficient way to draw an arbitrary number of images in a series inside a figure in Python using matplotlib.
This is what I want to achieve:
Each image will have a different width but the same height. Of course, we can use subplot but the problem with subplot images must have the same width plus the issue of spacing between different columns.
If I need to use another library/package to achieve that that is totally fine for me.
Notes:
The borders around each image should not exist but it is just for illustration.
I want to consider the figure as an area where I can plot images in any position and add text in a specific location.
You can use gridspec and specifying left, right, bottom, top, width_ratios and height_ratios to generate subplots in a very flexible way. Pls see doc for details.
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
nrows=2
ncols=2
fig = plt.figure(figsize=(7.2, 7.2))
gs = fig.add_gridspec(nrows=nrows, ncols=ncols, left=0.1, right=0.6, bottom=0.55, top=0.95, width_ratios=[1, 2], height_ratios=[1, 1])
axes = [fig.add_subplot(gs[row, col]) for row in range(nrows) for col in range(ncols)]
The following question arose while toying around with figure sizes. I am trying to create figures of the same size (let's say 5 by 5 inches). Thing is, when I change the notation of the colorbar, the figure size seems to change. In the code below, this can be achieved by changing the final if to tick_check=False. How can I force the figures to be the same size, regardless of the colorbar notation?
Here's my MWE:
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
def foo(arr, sub, fig, _str, vmin, vmax, ticks, fontsize, check, tick_check):
cm=plt.cm.jet
P2A=0.12; box_size=5
image=sub.matshow(arr,origin='low',cmap=cm,vmin=vmin,vmax=vmax,extent=[-10.92,10.92,-10.92,10.92],interpolation='bilinear')
sub.axis([-box_size,box_size,-box_size,box_size])
divider = make_axes_locatable(sub)
sub.set_title(_str,fontsize=fontsize); sub.set_xlabel(r"A",fontsize=fontsize); sub.set_ylabel(r"B",fontsize=fontsize)
if tick_check: cbar=fig.colorbar(image, cax=divider.append_axes("right", size="5%", pad=0.05), format='%.1E')
else: cbar=fig.colorbar(image, cax=divider.append_axes("right", size="5%", pad=0.05), format='%.1f')
cbar.set_ticks(ticks); sub.xaxis.tick_bottom(); sub.tick_params(labelsize=10);sub.set_title(_str, y=1.01); plt.tight_layout(h_pad=1)
d_arr=np.random.rand(182,182)
fig0, (a1) = plt.subplots(ncols=1,figsize=(5,5))
im=foo(d_arr,a1,fig0,r'Test',np.min(d_arr),np.max(d_arr),np.arange(np.min(d_arr),np.max(d_arr),0.1),10,False,True)
plt.savefig('Foo.eps',bbox_inches='tight',dpi=100)
Any help is appreciated.
Turns out, the solution to this problem is the keyword aspect, which needs to be set to auto. So:
image=sub.matshow(arr,origin='low',cmap=cm,vmin=vmin,vmax=vmax,extent=[-10.92,10.92,-10.92,10.92],interpolation='bilinear', aspect='auto')
I have a code to plot a figure.
When I run this code without adding plt.colorbar(), I can get a figure which looks more like a rectangle. However, if I add colorbar, the shape change to look like a square.
How can I add colorbar and maintain the original shape of the figure? Thanks!!!
#%%
import numpy as np
import matplotlib.pyplot as plt
fig = plt.figure()
x = np.random.rand(10000)
y = np.random.rand(10000)
plt.scatter(x,y,c=y)
#plt.colorbar()
plt.show()
Following this documentation, you need to add some settings to axes. Your script works for me in a right ways if I insert these rows after creation of fig:
ax = plt.gca()
ax.set_aspect('equal', 'box')
Normally if you plot two different figures using the default settings in pyplot, they will be exactly the same size, and if saved can be neatly aligned in PowerPoint or the like. I'd like to generate one figure, however, which has a legend outside of the figure. The script I'm using is shown below.
import numpy as np
import matplotlib.pyplot as plt
x=np.linspace(0,1,201)
y1=x**2
y2=np.sin(x)
fig1=plt.figure(1)
plt.plot(x,y1,label='y1')
handles1,labels1=plt.gca().get_legend_handles_labels()
lgd1=plt.gca().legend(handles1,labels1,bbox_to_anchor=(1.27,1),borderaxespad=0.)
fig2=plt.figure(2)
plt.plot(x,y2)
fig1.savefig('fig1',bbox_extra_artists=(lgd1,),bbox_inches='tight')
fig2.savefig('fig2')
plt.show()
The problem is that in PowerPoint, I can no longer align the two figures left and have their axes aligned. Due to the use of the 'extra artists' and 'bbox_inches=tight' arguments for the first figure, the width of its margins becomes different from the second figure.
Is there any way to 'transfer' the clip box from the first figure to the second figure, such that they can be aligned by 'align left' in PowerPoint?
I think an easier way to achieve what you want is to just construct one figure with two subplots, and let matplotlib align everything for you.
Do you think doing something like this is a good idea?
import matplotlib.pyplot as plt
import numpy as np
x=np.linspace(0,1,201)
y1=x**2
y2=np.sin(x)
fig = plt.figure()
a = fig.add_subplot(211)
a.plot(x,y1, label='y1')
lgd1 = a.legend(bbox_to_anchor = (1.27,1), borderaxespad=0.)
a = fig.add_subplot(212)
a.plot(x,y2)
fig.savefig('fig',bbox_extra_artists=(lgd1,),bbox_inches='tight')