将 Dataframe 中的文本添加到 Seaborn replot
Add Text from Dataframe to Seaborn relplot
我正在尝试将数据框中的文本,特别是数据集中两个时期之间的百分比差异,添加到具有多个子图的 seaborn relplot。
我创建了一个可执行示例:
import pandas as pd
import numpy as np
import seaborn as sns
#create dataframe
pd.set_option("display.max_columns", 200)
data = {'PTID': [11111, 11111, 11111, 11111, 22222, 22222, 22222, 22222, 33333, 33333, 33333, 33333, 44444, 44444, 44444, 44444, 55555, 55555, 55555, 55555],
'Period' : ['Baseline','p1','p2','p3','Baseline','p1','p2','p3','Baseline','p1','p2','p3', 'Baseline','p1','p2','p3', 'Baseline','p1','p2','p3'] ,
'ALK PHOS': [46.0, 94.0, 21.0, 18.0, 56.0, 104.0, 31.0, 12.0, 50.0, 100.0, 33.0, 18.0, 46.0, 94.0, 21.0, 18.0, 46.0, 94.0, 21.0, 18.0],
'AST (SGOT)': [33.0, 92.0, 19.0, 25.0, 33.0, 92.0, 21.0, 11.0, 33.0, 102.0, 18.0, 17.0, 23.0, 82.0, 13.0, 17.0, 23.0, 82.0, 13.0, 17.0],
'% Saturation- Iron': [34.0, 65.0, 10.0, 14.0, 34.0, 65.0, 10.0, 14.0, 34.0, 65.0, 10.0, 14.0, 34.0, 65.0, 10.0, 14.0, 34.0, 65.0, 10.0, 14.0]}
df = pd.DataFrame(data)
#melt into long format
dfm = df.melt(id_vars=['PTID','Period'], var_name='Metric',value_name='Value')
#get average of data for period
dfg = dfm.groupby(['PTID','Period', 'Metric'])['Value'].mean().reset_index()
#drop periods in between, only keep first and last
dfd = dfm[dfm['Period'].isin(['Baseline','p3'])]
#create dataframe with % difference between periods
dfdg = dfd.groupby(['Metric', 'Period'])['Value'].mean().reset_index()
dfp = pd.pivot(dfdg, values='Value', index=['Metric'],
columns=['Period']).reset_index()
dfp['Difference'] = ((dfp['p3'] - dfp['Baseline'])/dfp['Baseline'])*100
dfp = dfp.round(2)
#plot subplots
p = sns.relplot(data=dfd, col='Metric', x='Period', y='Value', hue = 'PTID',kind='scatter', col_wrap=5, marker='o', palette='tab10',facet_kws={'sharey': False, 'sharex': True},)
p.map(sns.lineplot, 'Period', 'Value', linestyle='--', color='gray', ci = None)
#add % change text to subplots
for row in dfp['Difference']:
print(row)
p.fig.text(0.5,0.5, str(row) + "%",fontsize=12)
我遇到的问题是,如果您 运行 代码,您会看到它在添加文本并将其全部放在最后一个图上时没有遍历子图。我想要达到的目标是每个
的百分比差异
dfp["difference"]
针对每个子图的特定指标。
我尝试遵循类似问题的现有示例 -
但代码不可执行,并且在使用“zip”功能时遇到问题。
这是我尝试实现“zip”功能的方式:
#add % change text to subplots
for idx, row in zip(g.axes,dfp['Difference']):
print(row)
p.fig.text(0.5,0.5, str(row) + "%",fontsize=12)
我知道坐标轴对我没有帮助,但我不确定如何访问子图。
问题是在 for 循环中没有指定 ax
来添加文本。通过将 for 循环更改为:
解决了此问题
#add % change text to subplots
for ax, row in zip(g.axes.flat,dfp['Difference']):
ax.text(0.75,0.75, str(row) + "%",fontsize=12,transform=ax.transAxes)
另一个需要注意的重要事项是必须添加 transform=ax.transAxes
以便相对于轴绘制文本。
我正在尝试将数据框中的文本,特别是数据集中两个时期之间的百分比差异,添加到具有多个子图的 seaborn relplot。
我创建了一个可执行示例:
import pandas as pd
import numpy as np
import seaborn as sns
#create dataframe
pd.set_option("display.max_columns", 200)
data = {'PTID': [11111, 11111, 11111, 11111, 22222, 22222, 22222, 22222, 33333, 33333, 33333, 33333, 44444, 44444, 44444, 44444, 55555, 55555, 55555, 55555],
'Period' : ['Baseline','p1','p2','p3','Baseline','p1','p2','p3','Baseline','p1','p2','p3', 'Baseline','p1','p2','p3', 'Baseline','p1','p2','p3'] ,
'ALK PHOS': [46.0, 94.0, 21.0, 18.0, 56.0, 104.0, 31.0, 12.0, 50.0, 100.0, 33.0, 18.0, 46.0, 94.0, 21.0, 18.0, 46.0, 94.0, 21.0, 18.0],
'AST (SGOT)': [33.0, 92.0, 19.0, 25.0, 33.0, 92.0, 21.0, 11.0, 33.0, 102.0, 18.0, 17.0, 23.0, 82.0, 13.0, 17.0, 23.0, 82.0, 13.0, 17.0],
'% Saturation- Iron': [34.0, 65.0, 10.0, 14.0, 34.0, 65.0, 10.0, 14.0, 34.0, 65.0, 10.0, 14.0, 34.0, 65.0, 10.0, 14.0, 34.0, 65.0, 10.0, 14.0]}
df = pd.DataFrame(data)
#melt into long format
dfm = df.melt(id_vars=['PTID','Period'], var_name='Metric',value_name='Value')
#get average of data for period
dfg = dfm.groupby(['PTID','Period', 'Metric'])['Value'].mean().reset_index()
#drop periods in between, only keep first and last
dfd = dfm[dfm['Period'].isin(['Baseline','p3'])]
#create dataframe with % difference between periods
dfdg = dfd.groupby(['Metric', 'Period'])['Value'].mean().reset_index()
dfp = pd.pivot(dfdg, values='Value', index=['Metric'],
columns=['Period']).reset_index()
dfp['Difference'] = ((dfp['p3'] - dfp['Baseline'])/dfp['Baseline'])*100
dfp = dfp.round(2)
#plot subplots
p = sns.relplot(data=dfd, col='Metric', x='Period', y='Value', hue = 'PTID',kind='scatter', col_wrap=5, marker='o', palette='tab10',facet_kws={'sharey': False, 'sharex': True},)
p.map(sns.lineplot, 'Period', 'Value', linestyle='--', color='gray', ci = None)
#add % change text to subplots
for row in dfp['Difference']:
print(row)
p.fig.text(0.5,0.5, str(row) + "%",fontsize=12)
我遇到的问题是,如果您 运行 代码,您会看到它在添加文本并将其全部放在最后一个图上时没有遍历子图。我想要达到的目标是每个
的百分比差异dfp["difference"]
针对每个子图的特定指标。
我尝试遵循类似问题的现有示例 -
但代码不可执行,并且在使用“zip”功能时遇到问题。
这是我尝试实现“zip”功能的方式:
#add % change text to subplots
for idx, row in zip(g.axes,dfp['Difference']):
print(row)
p.fig.text(0.5,0.5, str(row) + "%",fontsize=12)
我知道坐标轴对我没有帮助,但我不确定如何访问子图。
问题是在 for 循环中没有指定 ax
来添加文本。通过将 for 循环更改为:
#add % change text to subplots
for ax, row in zip(g.axes.flat,dfp['Difference']):
ax.text(0.75,0.75, str(row) + "%",fontsize=12,transform=ax.transAxes)
另一个需要注意的重要事项是必须添加 transform=ax.transAxes
以便相对于轴绘制文本。