This question already has answers here:
Matplotlib different size subplots
(6 answers)
Closed 1 year ago.
I was trying to achieve this
But i ended with this
The main idea was to manage axes to include the third subplot in the figure, but i can't find a way to do it. Can somebody help with that please.
import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-4*np.pi,4*np.pi,0.25)
np.sincx=np.sin(x)/x
plt.figure(num=3, figsize=(7,5))
plt.subplot(3,2,1)
plt.plot(x,np.sincx)
plt.subplot(3,2,2)
plt.plot(x,np.sincx,"ro")
fig = plt.figure()
ax = fig.add_axes((0.125,0.1,0.775,0.45))
plt.plot(x,np.sincx**2)
In your code, you are creating two figure, one with the two tops plots, and one with the bottom one. You need to only create one with multiple subplots!
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-4*np.pi,4*np.pi,0.25)
np.sincx = np.sin(x)/x
ax1 = plt.subplot(221)
ax1.plot(x,np.sincx)
ax2 = plt.subplot(222)
ax2.plot(x,-np.sincx,"ro")
ax3 = plt.subplot(212)
ax3.plot(x, np.sincx**2)
plt.show()
Output
With add_axes()
import numpy as np
import matplotlib.pyplot as plt
x = np.arange(-4*np.pi,4*np.pi,0.25)
np.sincx = np.sin(x)/x
fig = plt.figure()
ax1 = plt.subplot(221)
ax1.plot(x,np.sincx)
ax2 = plt.subplot(222)
ax2.plot(x,-np.sincx,"ro")
ax3 = fig.add_axes((0.125,0.1,0.775,0.45))
ax3.plot(x, np.sincx**2)
plt.show()
Output add_axes()
Related
Here is what I have. Is it possible to align bars in ax1 with the others?
image
import numpy as np
import matplotlib.pyplot as plt
x= np.arange(10)+.5
y = np.sin(x)
fig=plt.figure()
ax1 = plt.subplot(211)
ax2 = plt.subplot(223)
ax3 = plt.subplot(224)
ax1.bar(x,y)
ax2.bar(x[:5],y[:5])
ax3.bar(x[5:],y[5:])
plt.show()
I have a series of subplots in a single row, all sharing the same colorbar and I would like to use plt.tight_layout().
However when used naively, the colorbar messes everything up. Luckily, I found this in the matplotlib documentation, but it works only for one subplot.
Minimal Working Example
I tried to adapt it to multiple subplots but the subplot to which the colorbar is assigned to ends up being smaller.
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid1 import make_axes_locatable
import numpy as np
plt.close('all')
arr = np.arange(100).reshape((10, 10))
fig, ax = plt.subplots(ncols=2, figsize=(8, 4))
im0 = ax[0].imshow(arr, interpolation="none")
im1 = ax[1].imshow(arr, interpolation='none')
divider = make_axes_locatable(plt.gca())
cax = divider.append_axes("right", "5%", pad="3%")
plt.colorbar(im0, cax=cax)
plt.tight_layout()
This is what the result looks like.
With the newest matplotlib (3.6), there is a new option layout='compressed' for this situation:
import matplotlib.pyplot as plt
import numpy as np
arr = np.arange(100).reshape((10, 10))
fig, ax = plt.subplots(ncols=2, figsize=(4, 2), layout='compressed')
im0 = ax[0].imshow(arr)
im1 = ax[1].imshow(arr)
plt.colorbar(im0, ax=ax)
plt.show()
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.
I make 3d plots with matplotlib and I always get a weird frame with a normalized scale around my plot. Where does it come from and how can I get rid of it ?
Here is an example code that drives me to the problem :
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib import cm
from mpl_toolkits.mplot3d import Axes3D
x = np.linspace(0,10)
y = np.linspace(0,10)
z = np.linspace(0,10)
# ------------- Figure ---------------
fig, ax = plt.subplots(figsize = (9,6))
ax = fig.gca(projection='3d')
ax.plot(np.sin(x), np.cos(y), z)
plt.show()
And here is the result :
I use plt.subplots() because I want a figure with a 3D and a 2D plot side by side.
You call plt.subplots(...) and this, of course, instantiates an Axes, complete of horizontal and vertical spines, before Matplotlib is informed that you want a 3D enabled Axes.
When you later call plt.gca(...) it's too late…
Simply use
fig, ax = plt.subplots(figsize = (9,6), subplot_kw={"projection" : "3d"})
or
fig = plt.figure(figsize = (9,6))
ax = fig.add_subplot(111, projection='3d')
Addressing OP's comment
Figure.add_subplot is pretty flexible…
fig = plt.figure()
fig.add_subplot(1,5,(1,4), projection='3d')
fig.add_subplot(1,5,5)
fig.tight_layout()
plt.show()
I am new to Matplotlib, and as I am learning how to draw box plot in python, I was wondering if there is a way to show mean in the box plots?
Below is my code..
from pylab import *
import matplotlib.pyplot as plt
data1=np.random.rand(100,1)
data2=np.random.rand(100,1)
data_to_plot=[data1,data2]
#Create a figure instance
fig = plt.figure(1, figsize=(9, 6))
# Create an axes instance
axes = fig.add_subplot(111)
# Create the boxplot
bp = axes.boxplot(data_to_plot,**showmeans=True**)
Even though I have showmean flag on, it gives me the following error.
TypeError: boxplot() got an unexpected keyword argument 'showmeans'
This is a minimal example and produces the desired result:
import matplotlib.pyplot as plt
import numpy as np
data_to_plot = np.random.rand(100,5)
fig = plt.figure(1, figsize=(9, 6))
ax = fig.add_subplot(111)
bp = ax.boxplot(data_to_plot, showmeans=True)
plt.show()
EDIT:
If you want to achieve the same with matplotlib version 1.3.1 you'll have to plot the means manually. This is an example of how to do it:
import matplotlib.pyplot as plt
import numpy as np
data_to_plot = np.random.rand(100,5)
positions = np.arange(5) + 1
fig, ax = plt.subplots(1,2, figsize=(9,4))
# matplotlib > 1.4
bp = ax[0].boxplot(data_to_plot, positions=positions, showmeans=True)
ax[0].set_title("Using showmeans")
#matpltolib < 1.4
bp = ax[1].boxplot(data_to_plot, positions=positions)
means = [np.mean(data) for data in data_to_plot.T]
ax[1].plot(positions, means, 'rs')
ax[1].set_title("Plotting means manually")
plt.show()
Result:
You could also upgrade the matplotlib:
pip2 install matplotlib --upgrade
and then
bp = axes.boxplot(data_to_plot,showmeans=True)