[英]Legends are printing twice when calling matplotlib subplots
我正在 matplotlib 中編寫代碼以在子圖網格下打印多個直方圖,但是,當我最后調用 fig.legend() function 時,每個 plot 中的圖例都打印了兩次。 非常感謝有關如何解決此問題的任何指導:)這是我的代碼:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('darkgrid')
def get_cmap(n, name='hsv'):
return plt.cm.get_cmap(name, n)
def isSqrt(n):
sq_root = int(np.sqrt(n))
return (sq_root*sq_root) == n
df = pd.read_csv('mpg.csv')
df2 = pd.read_csv('dm_office_sales.csv')
df['miles'] = df2['salary']
numericClassifier = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
newdf = df.select_dtypes(numericClassifier)
columns = newdf.columns.tolist()
n = len(columns)
cmap = get_cmap(n)
if(isSqrt(n)):
nrows = ncols = int(np.sqrt(n))
else:
ncols = int(np.sqrt(n))
for i in range(ncols,50):
if ncols*i >= n:
nrows = i
break
else:
pass
fig,ax = plt.subplots(nrows,ncols)
count = 0
print(nrows,ncols)
for i in range(0,nrows,1):
for j in range(0,ncols,1):
print('ncols = {}'.format(j),'nrows = {}'.format(i),'count = {}'.format(count))
if count<=n-1:
plt_new = sns.histplot(df[columns[count]],ax=ax[i,j],facecolor=cmap(count),kde=True,edgecolor='black',label=df[columns[count]].name)
patches = plt_new.get_children()
for patch in patches:
patch.set_alpha(0.8)
color = patches[0].get_facecolor()
ax[i,j].set_xlabel('{}'.format(df[columns[count]].name))
ax[i,j].xaxis.label.set_fontsize(10)
ax[i,j].xaxis.label.set_fontname('ariel')
ax[i,j].set(xlabel=None)
ax[i,j].tick_params(axis='y', labelsize=8)
count+=1
else:
break
for i in range(0,nrows,1):
for j in range(0,ncols,1):
if not ax[i,j].has_data():
fig.delaxes(ax[i,j])
else:
pass
plt.suptitle('Histograms').set_fontname('ariel')
plt.tight_layout()
fig.legend(loc='upper right')
plt.show()
sns.histplot
似乎創建了兩個條形容器。 先是假人,再是真人。 (使用 seaborn 0.12.1 測試;這在其他版本中可能會有所不同。)因此,label 被分配給虛擬和真實的條形容器。 解決方法是刪除虛擬欄容器的 label。
這是改編后的代碼。 Seaborn 的mpg
數據集用於提供一個易於重現的示例。 由於hls
顏色圖的第一個和最后一個顏色是紅色, get_cmap(n + 1)
確保選擇了n
不同的 colors。 一些多余的代碼已被刪除。
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np
def get_cmap(n, name='hsv'):
return plt.cm.get_cmap(name, n)
sns.set_style('darkgrid')
df = sns.load_dataset('mpg')
numericClassifier = ['int16', 'int32', 'int64', 'float16', 'float32', 'float64']
newdf = df.select_dtypes(numericClassifier)
columns = newdf.columns.tolist()
n = len(columns)
cmap = get_cmap(n + 1)
ncols = int(np.sqrt(n))
nrows = int(np.ceil(n / ncols))
fig, ax = plt.subplots(nrows, ncols)
count = 0
print(nrows, ncols)
for i in range(0, nrows):
for j in range(0, ncols):
if count < n:
# print('ncols = {j}; nrows = {i}; count = {count}')
sns.histplot(df[columns[count]], ax=ax[i, j], facecolor=cmap(count), kde=True, edgecolor='black',
label=df[columns[count]].name)
ax[i, j].containers[0].set_label('') # seaborn seems to create a dummy bar container, remove its label
for patch in ax[i, j].get_children():
patch.set_alpha(0.8)
ax[i, j].tick_params(axis='y', labelsize=8)
count += 1
for i in range(0, nrows):
for j in range(0, ncols):
if not ax[i, j].has_data():
fig.delaxes(ax[i, j])
plt.suptitle('Histograms').set_fontname('ariel')
fig.legend(loc='upper right')
plt.tight_layout()
plt.subplots_adjust(right=0.75) # make extra space for the legend
plt.show()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.