我想在seaborn拍一个情节,但我遇到了一些困难.数据有两个变量:时间(2级)和状态(2级).我想在x轴上绘制时间,并表示为不同的子图,显示各个数据线.最后,在这些的右边,我想展示一个时间2和时间1之间的差异图,对于每个状态级别.我不能做得很好,因为我不能让第二个情节显示在右边.以下是我的try :

import numpy as np
import pandas as pd
import seaborn as sns

# Just making some fake data
ids = [1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5]
times = [1,1,2,2,1,1,2,2,1,1,2,2,1,1,2,2,1,1,2,2]
states = ['A', 'B', 'A', 'B'] * 5

np.random.seed(121)
resps = [(i*t) + np.random.normal() for i, t in zip(ids, times)]

DATA = {
    'identity': ids,
    'time': times,
    'state': states,
    'resps': resps
}
df = pd.DataFrame(DATA)
# Done with data

g = sns.relplot(
    data=df, kind='line',
    col='state', x='time', y='resps', units='identity',
    estimator=None, alpha=.5, height=5, aspect=.7)

# # Draw a line onto each Axes
g.map(sns.lineplot,"time", "resps", lw=5, ci=None)

# Make a wide data to make the difference
wide = df.set_index(['identity', 'state', 'time']).unstack().reset_index()

A = wide['state']=='A'
B = wide['state']=='B'

wide['diffA'] = wide[A][('resps', 2)] - wide[A][('resps', 1)]
wide['diffB'] = wide[B][('resps', 2)] - wide[B][('resps', 1)]

wide['difference'] = wide[['diffA', 'diffB']].sum(axis=1)
wide = wide.drop(columns=[('diffA', ''), ('diffB', '')])

sns.pointplot(x='state', y='difference', data=wide, join=False)

Output from the first enter image description here

And output from the second: enter image description here

Is there no way to put them together? Even though they are different data? I did try to use matplotlib. And then achieved slightly better results but this still had a problem because I wanted the two left plots to have a shared y axis but not the difference. This created lots of work as well, because I want to be flexible for different numbers of the state variable, but only kept to 2 for simplicity. Here is a paint version of what I want to do (sorry for the poor quality), hopefully with some more control over appearance but this is secondary: enter image description here

有没有可靠的方法以更简单的方式实现这一点?谢谢

推荐答案

问题在于,sns.relplot是以数字水平运行的.这意味着它会创建自己的图形对象,我们无法控制它使用的轴.如果要在不使用"纯"matplotlib的情况下利用seaborn创建线,可以在matplotlib轴上复制线:

import numpy as np
import pandas as pd
import seaborn as sns

# Just making some fake data
ids = [1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5]
times = [1,1,2,2,1,1,2,2,1,1,2,2,1,1,2,2,1,1,2,2]
states = ['A', 'B', 'A', 'B'] * 5

np.random.seed(121)
resps = [(i*t) + np.random.normal() for i, t in zip(ids, times)]

DATA = {
    'identity': ids,
    'time': times,
    'state': states,
    'resps': resps
}
df = pd.DataFrame(DATA)
# Done with data

g = sns.relplot(
    data=df, kind='line',
    col='state', x='time', y='resps', units='identity',
    estimator=None, alpha=.5, height=5, aspect=.7)

# # Draw a line onto each Axes
g.map(sns.lineplot,"time", "resps", lw=5, ci=None)

# Make a wide data to make the difference
wide = df.set_index(['identity', 'state', 'time']).unstack().reset_index()

A = wide['state']=='A'
B = wide['state']=='B'

wide['diffA'] = wide[A][('resps', 2)] - wide[A][('resps', 1)]
wide['diffB'] = wide[B][('resps', 2)] - wide[B][('resps', 1)]

wide['difference'] = wide[['diffA', 'diffB']].sum(axis=1)
wide = wide.drop(columns=[('diffA', ''), ('diffB', '')])

# New code ----------------------------------------
import matplotlib.pyplot as plt
plt.close(g.figure)

fig = plt.figure(figsize=(12, 4))

ax1 = fig.add_subplot(1, 3, 1)
ax2 = fig.add_subplot(1, 3, 2, sharey=ax1)
ax3 = fig.add_subplot(1, 3, 3)

l = list(g.axes[0][0].get_lines())
l2 = list(g.axes[0][1].get_lines())

for ax, g_ax in zip([ax1, ax2], g.axes[0]):
    l = list(g_ax.get_lines())
    for line in l:
        ax.plot(line.get_data()[0], line.get_data()[1], color=line.get_color(), lw=line.get_linewidth())
    ax.set_title(g_ax.get_title())

sns.pointplot(ax=ax3, x='state', y='difference', data=wide, join=False)
# End of new code ---------------------------------- 

plt.show()

Result: enter image description here

Python相关问答推荐

沿着数组中的轴计算真实条目

. str.替换pandas.series的方法未按预期工作

将输入管道传输到正在运行的Python脚本中

处理带有间隙(空)的duckDB上的重复副本并有效填充它们

如何在Django基于类的视图中有效地使用UTE和RST HTIP方法?

如何在Python数据框架中加速序列的符号化

将9个3x3矩阵按特定顺序排列成9x9矩阵

如何让这个星型模式在Python中只使用一个for循环?

所有列的滚动标准差,忽略NaN

joblib:无法从父目录的另一个子文件夹加载转储模型

CommandeError:模块numba没有属性generated_jit''''

如何在Python中使用Pandas将R s Tukey s HSD表转换为相关矩阵''

在代码执行后关闭ChromeDriver窗口

如何将一组组合框重置回无 Select tkinter?

在Django中重命名我的表后,旧表中的项目不会被移动或删除

504未连接IB API TWS错误—即使API连接显示已接受''

如何在Python中解析特定的文本,这些文本包含了同一行中的所有内容,

在pandas中,如何在由两列加上一个值列组成的枢轴期间或之后可靠地设置多级列的索引顺序,

如何计算Pandas 中具有特定条件的行之间的天差

生产者/消费者-Queue.get by list