簡體   English   中英

Matplotlib 散點圖子圖圖例相互覆蓋

[英]Matplotlib scatterplot subplot legends overwrite one another

我有一個散點圖,其中包含使用 for 循環生成的子圖。 在圖中,我試圖創建一個圖例,但每次渲染子圖和圖例時,圖例都會被下一個子圖覆蓋,因此生成的圖包含僅與最后一個子圖相關的圖例。 我希望圖例適用於所有子圖(即,它應包括 2019、2020、2021 和 2022 年)。 這是我的代碼,請告訴我如何調整它。

import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.patches

df = pd.read_excel(path)

spp = df.SPP.unique()

fig, axs = plt.subplots(nrows=8, ncols=4, figsize=(14, 14))

for spp_i, ax in zip(spp, axs.flat):
    df_1 = df[df['SPP'] == spp_i]
    labels = list(df_1.Year.unique())
    x = df_1['Length_mm']
    y = df_1['Weight_g']
    levels, categories = pd.factorize(df_1['Year'])
    colors = [plt.cm.tab10(i) for i in levels]
    handles = [matplotlib.patches.Patch(color=plt.cm.tab10(i), label=c) for i, c in enumerate(categories)]
    ax.scatter(x, y, c=colors)
    plt.legend(handles=handles)

plt.savefig('Test.png', bbox_inches='tight', pad_inches=0.1, dpi=600)

這是圖,您可以看到右下角的圖例僅適用於最后一個子圖。
在此處輸入圖像描述

使用標准 matplotlib 創建此類圖非常麻煩。Seaborn 自動執行了很多步驟。

在這種情況下,可以使用sns.relplot(...) 如果您不希望所有子圖都具有相同的 x 和/或 y 范圍,您可以添加facet_kws={'sharex': False, 'sharey': False})

各個子圖的大小通過height=控制,而寬度將計算為height乘以aspect col_wrap=告訴在開始新行之前將放置多少列子圖。

import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
import numpy as np

spp_list = ["Aeloria", "Baelun", "Caelondia", "Draeden", "Eldrida", "Faerun", "Gorandor", "Haldira", "Ilysium",
            "Jordheim", "Kaltara", "Lorlandia", "Myridia", "Nirathia", "Oakenfort"]
df = pd.DataFrame({'SPP': np.repeat(spp_list, 100),
                   'Year': np.tile(np.repeat(np.arange(2019, 2023), 25), 15),
                   'Length_mm': np.abs(np.random.randn(1500).cumsum()) + 10,
                   'Weight_g': np.abs(np.random.randn(1500).cumsum()) + 20})

g = sns.relplot(df, x='Length_mm', y='Weight_g', col='SPP', col_order=spp_list,
                hue='Year', palette='turbo',
                height=3, aspect=1.5, col_wrap=6,
                facet_kws={'sharex': False, 'sharey': False})
g.set_axis_labels(x_var='Length (mm)', y_var='Weight (g)', clear_inner=True)

g.fig.tight_layout()  # nicely fit supblots with their titles, labels and ticks
g.fig.subplots_adjust(right=0.97)  # space for the legend after fitting the subplots
plt.show()

sns.relplot 示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM