'基质'基于数据框的条件格式绘图

时间:2017-08-25 01:18:12

标签: python pandas matplotlib seaborn

我正在寻求以下方面的帮助:给定一个数据帧,我想显示一个'矩阵'绘图的值对应于表格中的一对,但是根据'热图'进行格式化。对应于该对的不同列的值。这是示例数据:

df_list = [('nyc', 'lax', 10,-10, -2,2),('nyc', 'chi', -9,9, -2,2),('nyc', 'sfo', -4,4,-1,1),('nyc', 'mia', 2,-2, 2,-2),('lax', 'chi', 5,-5, 1,-1),('lax', 'sfo', -8,8, 2,-2),
           ('lax', 'mia', -6,6,0,0),('chi', 'sfo', 9,-9, -1,1),('chi', 'mia', 1,-1,3,-3),('sfo', 'mia', -3,3, -2,2)]

df = pd.DataFrame(df_list, columns=['x', 'y','x-y','y-x','num1','num2']) 

所以在excel中,未格式化的结果可能看起来像显示了' x-y'中的值。 (下三角)和' y-x' (上三角)列

enter image description here

但是,我在python中想要的是根据' num1'中值的分布格式化的单元格。 (下三角)或' num2' (上三角)栏

我想实现下面的颜色格式(基于num1 / num2值,但我希望单元格中显示的值对应上面的矩阵

enter image description here

我知道seaborn热图功能,但我找不到建议来解释显示变量和格式变量之间的差异。任何建议或例子将不胜感激

1 个答案:

答案 0 :(得分:0)

我认为应该将问题分成两部分。给定列形式的数据,第一个是如何获得相应的相关矩阵。我们需要一个用于x-y / y-x(在下面的代码中称为p),另一个用于num1 / num2(在下面的代码中称为n)。由于两列只有相反的符号,我们可能会简化一些事情,使得上三角形只是减去两个情况下的低三角形。一旦完成,问题在于可视化确实是使用seaborn.heatmap的单行。

sns.heatmap(n, annot = p)

完整示例:

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

df_list = [('nyc', 'lax', 10,-10, -2,2),('nyc','chi',-9,9,-2,2),('nyc', 'sfo',-4,4,-1,1),
           ('nyc', 'mia', 2,-2, 2,-2),('lax','chi',5,-5,1,-1),('lax', 'sfo', -8,8, 2,-2),
           ('lax', 'mia', -6,6,0,0),('chi', 'sfo', 9,-9, -1,1),('chi', 'mia', 1,-1,3,-3),
           ('sfo', 'mia', -3,3, -2,2)]

df = pd.DataFrame(df_list, columns=['x', 'y','x-y','y-x','num1','num2'])

u = np.unique(df[["x","y"]].values)

p1 = df.pivot("y","x","x-y").reindex(u,u)
p2 = df.pivot("x","y","x-y").reindex(u,u) 
p = p1.combine_first(p2)
utri = np.triu(np.ones(p.shape)).astype(np.bool)
p.values[utri] = -p.values[utri]

n1 = df.pivot("y","x","num1").reindex(u,u)
n2 = df.pivot("x","y","num1").reindex(u,u) 
n = n1.combine_first(n2)
n.values[utri] = -n.values[utri]

# color according to n, labels according to p
sns.heatmap(n, annot = p, center=0, cmap="RdBu")

plt.show()

enter image description here