Python 计算两个数据集之间的间距(熊猫、matplotlib、填充已使用的数据集之间的间距)

Python 计算两个数据集之间的间距(熊猫、matplotlib、填充已使用的数据集之间的间距),python,pandas,dataframe,matplotlib,Python,Pandas,Dataframe,Matplotlib,我想询问关于如何计算由pandas dataframe组成的matplotlib中两个数据集之间的间隙长度的建议。理想情况下,我希望将这些间隙值写入绘图中,如果可能的话,还希望将它们包含到数据帧中。 下面是我的dataframe简化示例: import pandas as pd d = {'Mean-1': [0.195842, 0.295069, 0.321345, 0.773725], 'SEM-1': [0.001216, 0.002687, 0.005267, 0.029974], 'M

我想询问关于如何计算由pandas dataframe组成的matplotlib中两个数据集之间的间隙长度的建议。理想情况下,我希望将这些间隙值写入绘图中,如果可能的话,还希望将它们包含到数据帧中。 下面是我的dataframe简化示例:

import pandas as pd
d = {'Mean-1': [0.195842, 0.295069, 0.321345, 0.773725], 'SEM-1': [0.001216, 0.002687, 0.005267, 0.029974], 'Mean-2': [0.143103, 0.250505, 0.305767, 0.960804],'SEM-2': [0.000959, 0.001368, 0.003722, 0.150025], 'Atom Number': [1, 3, 5, 7]}
df=pd.DataFrame(d)
df

    Mean-1      SEM-1       Mean-2      SEM-2     Atom Number
0   0.195842    0.001216    0.143103    0.000959    1
1   0.295069    0.002687    0.250505    0.001368    3
2   0.321345    0.005267    0.305767    0.003722    5
3   0.773725    0.029974    0.960804    0.150025    7
然后我画了一个图,在这里我们可以看到两条线代表平均值1和平均值2,然后在每条线周围的阴影区域代表平均值的标准误差。这是针对选定的原子数完成的

import matplotlib.pyplot as plt

ax = df.plot(x='Atom Number', y=['Mean-1','Mean-2'])

y_1 = df['Mean-1']
y_2 = df['Mean-2']
x = df['Atom Number']

error_1 = df['SEM-1']
error_2 = df['SEM-1']

ax.fill_between(df['Atom Number'], y_1-error_1, y_1+error_1, alpha=0.2, edgecolor='#CC4F1B', facecolor='#FF9848')
ax.fill_between(df['Atom Number'], y_2-error_2, y_2+error_2, alpha=0.2, edgecolor='#3F7F4C', facecolor='#7EFF99')
plt.xticks(x)

我想做的是进一步计算每个残留物的间隙间隙仅为空白,因此线条和阴影区域(SEM)不重叠的空间。
还想知道我是否可以打印出绘图中的间距值?并将它们保存到列中。谢谢你的建议。

IIUC,你想要这样的东西吗:

import matplotlib.pyplot as plt

ax = df.plot(x='Atom Number', y=['Mean-1','Mean-2'], figsize=(15,8))

y_1 = df['Mean-1']
y_2 = df['Mean-2']
x = df['Atom Number']

error_1 = df['SEM-1']
error_2 = df['SEM-1']

ax.fill_between(df['Atom Number'], y_1-error_1, y_1+error_1, alpha=0.2, edgecolor='#CC4F1B', facecolor='#FF9848')
ax.fill_between(df['Atom Number'], y_2-error_2, y_2+error_2, alpha=0.2, edgecolor='#3F7F4C', facecolor='#7EFF99')
ax.fill_between(df['Atom Number'], y_1+error_1, y_2-error_2, alpha=.2, edgecolor='k', facecolor='blue')

for i in range(len(x)):
    gap = y_1[i]+error_1[i] - y_2[i]-error_2[i]
    ylabel = min(y_1[i], y_2[i]) + abs(gap) / 2
    _ = ax.annotate(f'{gap:0.4f}', xy=(x[i],ylabel), xytext=(x[i]-.14,y_1[i]+gap/abs(gap)*.2), arrowprops=dict(arrowstyle="-"))
plt.xticks(x);
输出:


IIUC,你想要这样的东西吗:

import matplotlib.pyplot as plt

ax = df.plot(x='Atom Number', y=['Mean-1','Mean-2'], figsize=(15,8))

y_1 = df['Mean-1']
y_2 = df['Mean-2']
x = df['Atom Number']

error_1 = df['SEM-1']
error_2 = df['SEM-1']

ax.fill_between(df['Atom Number'], y_1-error_1, y_1+error_1, alpha=0.2, edgecolor='#CC4F1B', facecolor='#FF9848')
ax.fill_between(df['Atom Number'], y_2-error_2, y_2+error_2, alpha=0.2, edgecolor='#3F7F4C', facecolor='#7EFF99')
ax.fill_between(df['Atom Number'], y_1+error_1, y_2-error_2, alpha=.2, edgecolor='k', facecolor='blue')

for i in range(len(x)):
    gap = y_1[i]+error_1[i] - y_2[i]-error_2[i]
    ylabel = min(y_1[i], y_2[i]) + abs(gap) / 2
    _ = ax.annotate(f'{gap:0.4f}', xy=(x[i],ylabel), xytext=(x[i]-.14,y_1[i]+gap/abs(gap)*.2), arrowprops=dict(arrowstyle="-"))
plt.xticks(x);
输出:


这不是一个紧凑的解决方案,但您可以尝试类似的方法(检查事情的顺序)。计算所有位置(
y_i
和上下限)

    Mean-1     SEM-1    Mean-2     SEM-2  Atom Number  y1_upper  y1_lower  \
0  0.195842  0.001216  0.143103  0.000959            1  0.197058  0.194626   
1  0.295069  0.002687  0.250505  0.001368            3  0.297756  0.292382   
2  0.321345  0.005267  0.305767  0.003722            5  0.326612  0.316078   
3  0.773725  0.029974  0.960804  0.150025            7  0.803699  0.743751   

   y2_upper  y2_lower     
0  0.144319  0.141887  
1  0.253192  0.247818  
2  0.311034  0.300500  
3  0.990778  0.930830  
根据
y_1
是否超过
y_2
以及反之亦然,距离(间隙)的计算方式有所不同。因此,使用上限和下限条件,并使用
linalg.norm
计算距离

conditions = [
    (df['y1_lower'] >= df['y2_upper']),
    (df['y1_lower'] < df['y2_upper'])]
choices = [np.linalg.norm(df['y1_lower']-df['y2_upper']), np.linalg.norm(df['y2_lower']-df['y1_upper'])]
df['dist'] = np.select(conditions, choices)

正如我所说,检查顺序,但这是一个可能的解决方案。

这不是一个紧凑的解决方案,但您可以尝试类似的方法(检查事情的顺序)。计算所有位置(
y_i
和上下限)

    Mean-1     SEM-1    Mean-2     SEM-2  Atom Number  y1_upper  y1_lower  \
0  0.195842  0.001216  0.143103  0.000959            1  0.197058  0.194626   
1  0.295069  0.002687  0.250505  0.001368            3  0.297756  0.292382   
2  0.321345  0.005267  0.305767  0.003722            5  0.326612  0.316078   
3  0.773725  0.029974  0.960804  0.150025            7  0.803699  0.743751   

   y2_upper  y2_lower     
0  0.144319  0.141887  
1  0.253192  0.247818  
2  0.311034  0.300500  
3  0.990778  0.930830  
根据
y_1
是否超过
y_2
以及反之亦然,距离(间隙)的计算方式有所不同。因此,使用上限和下限条件,并使用
linalg.norm
计算距离

conditions = [
    (df['y1_lower'] >= df['y2_upper']),
    (df['y1_lower'] < df['y2_upper'])]
choices = [np.linalg.norm(df['y1_lower']-df['y2_upper']), np.linalg.norm(df['y2_lower']-df['y1_upper'])]
df['dist'] = np.select(conditions, choices)
正如我所说,检查订单,但这是一个可能的解决方案