use*_*775 7 python matplotlib seaborn seaborn-0.12.x
我正在创建一个图形(带有seaborn.objects界面),需要带有颜色和标记的图例。我正在尝试移动生成的图例,但在移动标记部分时遇到问题。请参阅下面的示例:
该示例旨在在笔记本环境中运行。添加plt.show()以在作为 Python 文件运行时显示图形。
import matplotlib.pyplot as plt
import seaborn as sns
import seaborn.objects as so
mpg = sns.load_dataset("mpg")
f, axs = plt.subplots(1, 2, figsize=(8, 4))
_ = (
so.Plot(mpg, "weight", "acceleration", color="cylinders")
.add(so.Dot(), marker="origin")
.scale(
color=["#49b", "#a6a", "#5b8", "#128", "#332"],
marker={"japan": ".", "europe": "+", "usa": "*"},
)
.on(axs[0])
.plot()
)
Run Code Online (Sandbox Code Playgroud)
我试图将图例从情节的最右侧移动到子情节的右侧。如何使用 Seaborn 0.12 对象自定义图例?在这种情况下只是部分解决方案。仅部分图例移动成功。我想知道为什么没有看到传说的第二部分......legend_handles
l1 = f.legends.pop(0)
axs[0].legend(l1.legend_handles, [t.get_text() for t in l1.texts])
Run Code Online (Sandbox Code Playgroud)
传奇的所有部分如何移动?
免责声明:这是一个黑客解决方案,可能不适用于所有情况。我开发它时只考虑到了这个问题,所以我不能保证它会有效地推广。如果这不涵盖您的特定用例,请发表评论。
该解决方案有两个关键要素:
plotter._legend_contentsseaborn图例创建过程中使用的实用方法,adjust_legend_subtitles以重新创建带有样式字幕的图例seaborn。我已调整问题中的示例以在笔记本环境中运行,并且我已包含该问题的解决方案。见下文:
import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns
import seaborn.objects as so
sns.set_theme(style="white")
mpg = sns.load_dataset("mpg")
fig, axs = plt.subplots(1, 2, figsize=(8, 4))
ax = axs[0]
plotter = (
so.Plot(mpg, "weight", "acceleration", color="cylinders")
.add(so.Dot(), marker="origin")
.scale(
color=["#49b", "#a6a", "#5b8", "#128", "#332"],
marker={"japan": ".", "europe": "+", "usa": "*"},
)
.on(ax)
.plot()
)
# --- Solution begins here --- #
legend_contents = plotter._legend_contents
blank_handle = mpl.patches.Patch(alpha=0, linewidth=0, visible=False)
handles = []
labels = []
for legend_content in legend_contents:
handles.append(blank_handle)
handles.extend(legend_content[1])
labels.append(legend_content[0][0])
labels.extend(legend_content[2])
axs[0].legend(handles, labels)
def adjust_legend_subtitles(legend):
font_size = plt.rcParams.get("legend.title_fontsize", None)
hpackers = legend.findobj(mpl.offsetbox.VPacker)[0].get_children()
for hpack in hpackers:
draw_area, text_area = hpack.get_children()
handles = draw_area.get_children()
handle = handles[0]
if not handles[0]._visible:
draw_area.set_width(0)
for text in text_area.get_children():
if font_size is not None:
text.set_size(font_size)
adjust_legend_subtitles(ax.get_legend())
fig.legends.pop(0)
# --- Optional! --- #
# After this move, you can use sns.move_legend to move the legend where
# you want it. However, you will have to call adjust_legend_subtitles
# again to get the "subtitle" formatting back.
sns.move_legend(ax, "best")
adjust_legend_subtitles(axs[0].get_legend())
Run Code Online (Sandbox Code Playgroud)
该解决方案在以下版本上进行了测试:
| 归档时间: |
|
| 查看次数: |
253 次 |
| 最近记录: |