提问人:diyer0001 提问时间:8/29/2023 最后编辑:Trenton McKinneydiyer0001 更新时间:8/30/2023 访问量:92
如何使用 mplcursors 对多网格图中的完整数据帧行进行注释
How to use mplcursors to annotate with a complete dataframe row in a multigrid plot
问:
我正在尝试绘制跨多个视觉属性(面、色调、形状、x、y)的多维散点图。我还尝试在光标悬停时获得工具提示,以显示该点的其他属性。(我正在使用 seaborn + mplcursors,但我没有嫁给这个解决方案。问题在于悬停在数据集中的索引错误,并显示错误的信息。您可以在以下玩具示例中看到相同的内容,该示例由 seaborn 和 mplcursors 网站中的两个示例组装而成。
我相信我已经诊断出 cursor.connect() 的问题没有在数据帧中返回正确的索引。如果我减少修饰符(色调、列、行等)的数量,我可以让这个例子起作用,但它不适用于所有这些修饰符。
import seaborn as sns
import matplotlib.pyplot as plt
import mplcursors
df = sns.load_dataset("tips")
sns.relplot(data=df, x="total_bill", y="tip", hue="day", col="time", row="sex")
def show_hover_panel(get_text_func=None):
cursor = mplcursors.cursor(
hover=2, # Transient
annotation_kwargs=dict(
bbox=dict(
boxstyle="square,pad=0.5",
facecolor="white",
edgecolor="#ddd",
linewidth=0.5,
),
linespacing=1.5,
arrowprops=None,
),
highlight=True,
highlight_kwargs=dict(linewidth=2),
)
if get_text_func:
cursor.connect(
event="add",
func=lambda sel: sel.annotation.set_text(get_text_func(sel.index)), # <- this doesn't appear to return the correct integer index in the dataframe
)
return cursor
def on_add(index):
item = df.iloc[index]
parts = [
f"total_bill: {item.total_bill}",
f"tip: {item.tip}",
f"day: ${item.day}",
f"time: ${item.time}",
f"sex: ${item.sex}",
]
return "\n".join(parts)
show_hover_panel(on_add)
plt.show()
我试过什么:
- 最小可行示例
- 删除修饰符 = 有效
- 根据数据追溯正确的点位置,但是当我将索引传递给工具提示时,我注意到索引与数据帧中的正确索引不对应。
答:
1赞
JohanC
8/30/2023
#1
sns.relplot
返回包含 .这是一个字典,每一列和每一行都告诉哪个是相应的子图()。基于此,您可以创建一个新字典,将 映射到数据帧的相应子集。(请注意,这可能会占用大型数据帧的大量额外内存。FacetGrid
axes_dict
ax
ax
中选定的艺术家保留对子情节 () 的引用,该子情节可用作新词典中的键。mplcursors
set.artist.axes
下面是示例的样子。注释函数现在更大了,所以它需要自己的函数。
import seaborn as sns
import matplotlib.pyplot as plt
import mplcursors
df = sns.load_dataset("tips")
g = sns.relplot(data=df, x="total_bill", y="tip", hue="day", col="time", row="sex")
# create a dictionary mapping subplots to their corresponding subset of the dataframe
subplot_df_dict = dict()
for (sex, time), ax in g.axes_dict.items():
subplot_df_dict[ax] = df[(df['sex'] == sex) & (df['time'] == time)].reset_index(drop=True)
def show_annotation(sel):
ax = sel.artist.axes
item = subplot_df_dict[ax].iloc[sel.index]
parts = [
f"total_bill: {item.total_bill}",
f"tip: {item.tip}",
f"day: ${item.day}",
f"time: ${item.time}",
f"sex: ${item.sex}",
]
sel.annotation.set_text("\n".join(parts))
def show_hover_panel(show_annotation_func=None):
cursor = mplcursors.cursor(
hover=2, # Transient
annotation_kwargs=dict(
bbox=dict(
boxstyle="square,pad=0.5",
facecolor="white",
edgecolor="#ddd",
linewidth=0.5,
),
linespacing=1.5,
arrowprops=None,
),
highlight=True,
highlight_kwargs=dict(linewidth=2),
)
if show_annotation_func is not None:
cursor.connect(
event="add",
func=show_annotation_func
)
return cursor
show_hover_panel(show_annotation)
plt.show()
评论
0赞
diyer0001
9/1/2023
这行得通。多谢!
评论
mplcursors
relplot
col
row
mplcursors