Seaborn Facet Grid 图例重叠

Seaborn Facet Grid legend overlapping

我正在尝试绘制一个 Seaborn FacetGrid,所有四个方面都有一个图例。我不希望图例与小平面重叠,但是,我确实希望图例显示所有数据的句柄,而不仅仅是最后一个小平面的句柄。我可以让图例正确定位,或者让所有手柄显示,但不能同时显示。我看过其他答案,但似乎找不到解决方案。在 post 中,我包含了说明问题的图像(使用我的完整数据集,而不是下面代码中生成的数据集)。

import pandas as pd
from datetime import datetime
from random import random, randrange
import matplotlib.pyplot as plt
from matplotlib import dates
import seaborn as sns

# Create a dataframe to test on
df = pd.DataFrame(columns=['WindowID', 'Date_Time', 'Occlusion', 'Floor', 'Month'])
dict = {'Month': [5, 8, 10, 11],
        'Day': [15, 18, 30, 10]}
for j in range(4):
    mon = dict['Month'][j]
    dy = dict['Day'][j]
    for i in range(10):
        x = i+1
        floor = randrange(1,12)
        hr = 9
        while hr < 18:
            z = random()
            y = datetime(year=2019, month=mon, day=dy, hour=hr, minute=00, second=00)
            df = df.append({'WindowID': x, 'Date_Time': y, 'Occlusion': z, 'Floor': floor, 'Month':mon}, ignore_index=True)
            hr += 2


subset_sel = 'Northeast'
byhue = 'Floor'

# This method produces the desired outcome, except that the legend overlaps the last facet
# Note: adding legend_out=True to sns.FacetGrid, does not change outcome
g = sns.FacetGrid(df, hue='Floor', col="Month", sharex=False, sharey=True)
g.map(sns.lineplot, "Date_Time", "Occlusion", legend="full")

for ax in g.axes.flatten():
    ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
    ax.xaxis.set_major_formatter(dates.DateFormatter("%H:%M"))
    ax.set_xticks(ax.get_xticks()[::2])

g.add_legend()
g.set_axis_labels("Hour", "Occlusion")
g.set(ylim=(0, 1.0))
plt.suptitle('Northeast', y=0.98, fontsize=14)
plt.tight_layout()
plt.show()

我试过很多东西:

  1. 下面的代码生成了带有所有句柄但重叠的图例。
  2. 使用 plt.legend(bbox_to_anchor=(1.04, 1), borderaxespad=0, title='Floor') 而不是 g.add_legend() 会生成位于构面之外但不包含所有构面的所有句柄的图例。
  3. plt.subplots_adjust(right=0.7)
  4. g.add_legend(bbox_to_anchor=(1.04, 0), loc=2, borderaxespad=0.)
  5. 删除 plt.tight_layout 会切断 x 轴标签。

如有任何帮助,我们将不胜感激!

Facet Grid Plots with all handles, but overlapping last facet Facet Grid Plots with legend not overlapping, but missing handles 10 and 11

您的问题源于 plt.tight_layout() 的使用,它试图调整轴的边距以确保所有标签都可见,但不知道 space 所需的图例.

如您所述,如果您删除 plt.tight_layout()FacetGrid 会为右侧的图例留出空间,但由于旋转,您的 x 标签会从图中突出。所以我的建议是保留 FacetGrid 的布局,但使用 plt.subplots_adjust(bottom=0.25)

为 x-tick 标签腾出更多空间
grid.map(sns.lineplot, 'transaction_date', 'units', alpha=0.5).add_legend()
grid.fig.set_size_inches(plt.rcParams['figure.figsize'])
plt.tight_layout()
# include_zero_on_y_axis(grid)
plt.show()

g = sns.FacetGrid(df, hue='Floor', col="Month", sharex=False, sharey=True)
g.map(sns.lineplot, "Date_Time", "Occlusion", legend="full")

for ax in g.axes.flatten():
    ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
    ax.xaxis.set_major_formatter(dates.DateFormatter("%H:%M"))
    ax.set_xticks(ax.get_xticks()[::2])

l = g.add_legend()
g.set_axis_labels("Hour", "Occlusion")
g.set(ylim=(0, 1.0))
plt.suptitle('Northeast', y=0.98, fontsize=14)
plt.subplots_adjust(bottom=0.25)
plt.show()