python : 使用一个子图作为其他子图的图例
python : using a subplot as legend for the others subplots
我有下面的脚本生成一个由 5 个直方图(5 个子图)组成的图:
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from scipy.optimize import curve_fit
mean_o = list()
sigma_o = list()
y3 = list()
### generate some data
for i in range( 5 ):
y3.append( norm.rvs( size=150000 ) )
y3 = np.transpose( y3 )
for i in range(5):
mean_o.append( np.mean( y3[ :, i ] ) )
sigma_o.append( np.std( y3[ :, i ] ) )
## Histograms
# Number of bins
Nbins=100
binwidth = np.zeros(5)
# Fitting curves
def gaussian( x, a , mean, sigma ):
return a * np.exp( -( ( x - mean )**2 / (2 * sigma**2 ) ) )
fig = plt.figure()
ax = { i : fig.add_subplot( 2, 3, i+1) for i in range( 5 ) }
for i in range(5):
ymin = min(y3[:,i])
ymax = max(y3[:,i])
binwidth[i] = ( ymax - ymin) / Nbins
bins_plot = np.arange( ymin, ymax + binwidth[i], binwidth[i])
histdata = ax[i].hist(
y3[:,i],
bins=bins_plot,
label='bin '+str(i)
)
range_fit = np.linspace( ymin, ymax, 250)
# Fitting and plot version 1
popt, pcov = curve_fit(
gaussian,
0.5 * ( histdata[1][:-1] + histdata[1][1:] ),
histdata[0],
p0=( max(histdata[0]), mean_o[i], sigma_o[i] ) )
ax[i].plot(range_fit, gaussian( range_fit, *popt ) )
ax[i].axvline( x=mean_o[i], ls=':', c='r' )
# Fitting and plot version 2
params = norm.fit( y3[ ::, i ], loc=mean_o[i], scale=sigma_o[i] )
nth = gaussian(
range_fit,
len( y3[::, i]) * binwidth[i] / np.sqrt( 2 * np.pi ),
*params
)
ax[i].plot(range_fit, nth, ls="--" )
plt.tight_layout()
plt.show()
即生成下图:
现在,我想在右下角的第 6 个子图中使用作为其他 5 个子图的图例,其中最佳拟合值与每个子图对应的框和值一起出现(如颜色代码):
我完全不知道如何将次要情节用作图例,有人知道吗?
您可以创建一个额外的子图并放置一个custom legend in it. The custom legend could use dummy handles and a list of labels. To customize how the legend looks,可以使用许多参数。 ax.axes('off')
将关闭最后一个子图不需要的周围轴。
这是一些示例代码。为了简化计算,y3
用二维numpy数组表示。
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from scipy.optimize import curve_fit
### generate some data
y3 = norm.rvs(size=(5, 5000))
mean_o = np.mean(y3, axis=1)
sigma_o = np.std(y3, axis=1)
## Histograms
# Number of bins
Nbins = 100
# Fitting curves
def gaussian(x, a, mean, sigma):
return a * np.exp(-((x - mean) ** 2 / (2 * sigma ** 2)))
fig = plt.figure(figsize=(15, 7))
ax = {i: fig.add_subplot(2, 3, i + 1) for i in range(5)}
ymin = y3.min(axis=1)
ymax = y3.max(axis=1)
legend_labels = []
for i in range(5):
bins_plot = np.linspace(ymin[i], ymax[i], Nbins + 1)
values, bins, patches = ax[i].hist(
y3[i],
bins=bins_plot,
label='bin ' + str(i))
range_fit = np.linspace(ymin[i], ymax[i], 250)
# Fitting and plot version 1
popt, pcov = curve_fit(
gaussian,
0.5 * (bins[:-1] + bins[1:]),
values,
p0=(values.max(), mean_o[i], sigma_o[i]))
ax[i].plot(range_fit, gaussian(range_fit, *popt))
ax[i].axvline(x=mean_o[i], ls=':', c='r')
# Fitting and plot version 2
params = norm.fit(y3[::, i], loc=mean_o[i], scale=sigma_o[i])
nth = gaussian(
range_fit,
len(y3[::, i]) * binwidth[i] / np.sqrt(2 * np.pi),
*params
)
ax[i].plot(range_fit, nth, ls="--")
legend_labels.append(f'bin {i + 1}: {mean_o[i]:.5f}')
ax5 = fig.add_subplot(2, 3, 6)
dummy_handle = plt.Rectangle((0, 0), 0, 0, color='none')
ax5.legend(handles=[dummy_handle] * len(legend_labels), labels=legend_labels,
handlelength=0, handletextpad=0, fontsize=24,
loc='center', shadow=True, facecolor='lightgrey')
ax5.axis('off')
plt.tight_layout()
plt.show()
我有下面的脚本生成一个由 5 个直方图(5 个子图)组成的图:
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from scipy.optimize import curve_fit
mean_o = list()
sigma_o = list()
y3 = list()
### generate some data
for i in range( 5 ):
y3.append( norm.rvs( size=150000 ) )
y3 = np.transpose( y3 )
for i in range(5):
mean_o.append( np.mean( y3[ :, i ] ) )
sigma_o.append( np.std( y3[ :, i ] ) )
## Histograms
# Number of bins
Nbins=100
binwidth = np.zeros(5)
# Fitting curves
def gaussian( x, a , mean, sigma ):
return a * np.exp( -( ( x - mean )**2 / (2 * sigma**2 ) ) )
fig = plt.figure()
ax = { i : fig.add_subplot( 2, 3, i+1) for i in range( 5 ) }
for i in range(5):
ymin = min(y3[:,i])
ymax = max(y3[:,i])
binwidth[i] = ( ymax - ymin) / Nbins
bins_plot = np.arange( ymin, ymax + binwidth[i], binwidth[i])
histdata = ax[i].hist(
y3[:,i],
bins=bins_plot,
label='bin '+str(i)
)
range_fit = np.linspace( ymin, ymax, 250)
# Fitting and plot version 1
popt, pcov = curve_fit(
gaussian,
0.5 * ( histdata[1][:-1] + histdata[1][1:] ),
histdata[0],
p0=( max(histdata[0]), mean_o[i], sigma_o[i] ) )
ax[i].plot(range_fit, gaussian( range_fit, *popt ) )
ax[i].axvline( x=mean_o[i], ls=':', c='r' )
# Fitting and plot version 2
params = norm.fit( y3[ ::, i ], loc=mean_o[i], scale=sigma_o[i] )
nth = gaussian(
range_fit,
len( y3[::, i]) * binwidth[i] / np.sqrt( 2 * np.pi ),
*params
)
ax[i].plot(range_fit, nth, ls="--" )
plt.tight_layout()
plt.show()
即生成下图:
现在,我想在右下角的第 6 个子图中使用作为其他 5 个子图的图例,其中最佳拟合值与每个子图对应的框和值一起出现(如颜色代码):
我完全不知道如何将次要情节用作图例,有人知道吗?
您可以创建一个额外的子图并放置一个custom legend in it. The custom legend could use dummy handles and a list of labels. To customize how the legend looks,可以使用许多参数。 ax.axes('off')
将关闭最后一个子图不需要的周围轴。
这是一些示例代码。为了简化计算,y3
用二维numpy数组表示。
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import norm
from scipy.optimize import curve_fit
### generate some data
y3 = norm.rvs(size=(5, 5000))
mean_o = np.mean(y3, axis=1)
sigma_o = np.std(y3, axis=1)
## Histograms
# Number of bins
Nbins = 100
# Fitting curves
def gaussian(x, a, mean, sigma):
return a * np.exp(-((x - mean) ** 2 / (2 * sigma ** 2)))
fig = plt.figure(figsize=(15, 7))
ax = {i: fig.add_subplot(2, 3, i + 1) for i in range(5)}
ymin = y3.min(axis=1)
ymax = y3.max(axis=1)
legend_labels = []
for i in range(5):
bins_plot = np.linspace(ymin[i], ymax[i], Nbins + 1)
values, bins, patches = ax[i].hist(
y3[i],
bins=bins_plot,
label='bin ' + str(i))
range_fit = np.linspace(ymin[i], ymax[i], 250)
# Fitting and plot version 1
popt, pcov = curve_fit(
gaussian,
0.5 * (bins[:-1] + bins[1:]),
values,
p0=(values.max(), mean_o[i], sigma_o[i]))
ax[i].plot(range_fit, gaussian(range_fit, *popt))
ax[i].axvline(x=mean_o[i], ls=':', c='r')
# Fitting and plot version 2
params = norm.fit(y3[::, i], loc=mean_o[i], scale=sigma_o[i])
nth = gaussian(
range_fit,
len(y3[::, i]) * binwidth[i] / np.sqrt(2 * np.pi),
*params
)
ax[i].plot(range_fit, nth, ls="--")
legend_labels.append(f'bin {i + 1}: {mean_o[i]:.5f}')
ax5 = fig.add_subplot(2, 3, 6)
dummy_handle = plt.Rectangle((0, 0), 0, 0, color='none')
ax5.legend(handles=[dummy_handle] * len(legend_labels), labels=legend_labels,
handlelength=0, handletextpad=0, fontsize=24,
loc='center', shadow=True, facecolor='lightgrey')
ax5.axis('off')
plt.tight_layout()
plt.show()