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()
我试过很多东西:
- 下面的代码生成了带有所有句柄但重叠的图例。
- 使用
plt.legend(bbox_to_anchor=(1.04, 1), borderaxespad=0, title='Floor')
而不是 g.add_legend()
会生成位于构面之外但不包含所有构面的所有句柄的图例。
plt.subplots_adjust(right=0.7)
g.add_legend(bbox_to_anchor=(1.04, 0), loc=2, borderaxespad=0.)
- 删除
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()
我正在尝试绘制一个 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()
我试过很多东西:
- 下面的代码生成了带有所有句柄但重叠的图例。
- 使用
plt.legend(bbox_to_anchor=(1.04, 1), borderaxespad=0, title='Floor')
而不是g.add_legend()
会生成位于构面之外但不包含所有构面的所有句柄的图例。 plt.subplots_adjust(right=0.7)
g.add_legend(bbox_to_anchor=(1.04, 0), loc=2, borderaxespad=0.)
- 删除
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)
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()