python - 在 python pandas 数据框中使用精确颜色重叠透明区域的自定义图例 stacked=false?

标签 python pandas matplotlib

使用 pandas dataframe.plot 生成未堆叠面积图时,获得的彩色表面比图例条目的数量还要多。

考虑:

import pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randn(11, 3)+3, columns=['A', 'B', 'C'])

>>> print df

给予例如:

           A         B         C
0   1.908785  2.516292  4.139940
1   2.566306  3.275534  3.889655
2   2.083525  2.554483  3.565328
3   1.406931  2.021886  2.956590
4   3.293099  3.672927  3.203007
5   3.542735  1.301354  3.259613
6   1.331992  4.882820  2.165666
7   2.670735  3.763886  3.290484
8   4.211895  0.923923  3.415861
9   3.664398  2.009058  2.436214
10  2.707552  3.149282  1.629846

df.plot(kind='area', stacked=False)

制作:

对于三个数据系列或数据框中的列,有七个不同颜色的表面:以 A、B、C 为基础,有 AB、AC、BC 对,以及所有对的重叠:ABC。

尝试在 pyplot 中用重叠的圆圈将其可视化,如下所示:

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

plt.figure()

circle1 = plt.Circle((3, 3), radius=3, fc='r', alpha=0.5, edgecolor=None)
circle2 = plt.Circle((3, 7), radius=3, fc='g', alpha=0.5, edgecolor=None)
circle3 = plt.Circle((6, 5), radius=3, fc='b', alpha=0.5, edgecolor=None)
circles = [circle1, circle2, circle3]
for cle in circles:
    plt.gca().add_patch(cle)

plt.axis('scaled')
plt.xlim(0, 10)

现在,我学习了如何使用 line2D 对象在 pyplot 中制作具有特定颜色的自定义图例,如下所示:

circ1 = Line2D([0], [0], linestyle='none', marker='s', alpha=0.5,
               markersize=10, markerfacecolor='r')
circ2 = Line2D([0], [0], linestyle='none', marker='s', alpha=0.5,
               markersize=10, markerfacecolor='g')
circ3 = Line2D([0], [0], linestyle='none', marker='s', alpha=0.5,
               markersize=10, markerfacecolor="blue")

plt.legend((circ1, circ2, circ3), ('A', 'B', 'C'), numpoints=1, loc='best')

产生以下输出:

但是如何从未堆叠区域的原始 pandas 图中获取重叠表面的确切颜色,从而提供一种创建具有七个条目的图例的方法?

另请注意,此处的颜色略有不同。一方面,在 pandas 中,加色会产生较深的红色阴影(尽管这似乎随着绘制的数据帧的数据系列/列的数量而变化),另一方面 pyplot 会产生较深的蓝色阴影。

最佳答案

您可以手动计算混合颜色。例如,使用我发现的算法 here (我使用了稍微不同的 alpha 计算),我得到这样的结果:

enter image description here

为了更轻松地将图例项与重叠圆圈的混合颜色进行比较,我将图例项用 Photoshop 处理到图中(圆圈边缘的小方 block )。

import matplotlib.pyplot as plt
from matplotlib.lines import Line2D

plt.figure()

# cf = foreground color, cb = background color 
def mix_colors(cf, cb):
    a = cb[-1] + cf[-1] - cb[-1] * cf[-1] # fixed alpha calculation
    r = (cf[0] * cf[-1] + cb[0] * cb[-1] * (1 - cf[-1])) / a
    g = (cf[1] * cf[-1] + cb[1] * cb[-1] * (1 - cf[-1])) / a
    b = (cf[2] * cf[-1] + cb[2] * cb[-1] * (1 - cf[-1])) / a
    return [r,g,b,a]

c1 = [1.0, 0.1, 0.1, 0.5]
c2 = [0.3, 0.2, 0.7, 0.5]
c3 = [0.5, 0.8, 0.5, 0.5]

c12  = mix_colors(c2, c1) # mix c2 over c1
c13  = mix_colors(c3, c1) # mix c3 over c1
c123 = mix_colors(c3, c12) # mix c3 over c12

circle1 = plt.Circle((3, 3), radius=3, fc=c1, edgecolor=None)
circle2 = plt.Circle((3, 7), radius=3, fc=c2, edgecolor=None)
circle3 = plt.Circle((6, 5), radius=3, fc=c3, edgecolor=None)
circles = [circle1, circle2, circle3]
for cle in circles:
    plt.gca().add_patch(cle)

plt.axis('scaled')
plt.xlim(0, 10)

circ1 = Line2D([0], [0], linestyle='none', marker='s',
               markersize=10, markerfacecolor=c1)
circ2 = Line2D([0], [0], linestyle='none', marker='s',
               markersize=10, markerfacecolor=c2)
circ3 = Line2D([0], [0], linestyle='none', marker='s',
               markersize=10, markerfacecolor=c3)
circ4 = Line2D([0], [0], linestyle='none', marker='s',
               markersize=10, markerfacecolor=c12)
circ5 = Line2D([0], [0], linestyle='none', marker='s',
               markersize=10, markerfacecolor=c13)
circ6 = Line2D([0], [0], linestyle='none', marker='s',
               markersize=10, markerfacecolor=c123)

plt.legend((circ1, circ2, circ3, circ4, circ5, circ6), ('A', 'B', 'C', 'AB', 'AC', 'ABC'), numpoints=1, loc='best')

关于python - 在 python pandas 数据框中使用精确颜色重叠透明区域的自定义图例 stacked=false?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34090694/

相关文章:

python - WxPython 符号的使用

python - 使用 matplotlib 在同一图表上绘制 pandas 数据帧中的线条和条形图

python - 为 Python 2.7.12 安装 numpy、cython、cpython

python - 将 1 分钟间隔内的最后一个值分配给 pandas DataFrame 的行

sql - 将大量数据集从 SQL 服务器导入 HDF5

python - seaborn 联合图中的附加关键字参数

python - 如何将 seaborn boxplot 须基于百分位数?

Python 未绑定(bind)本地错误

Python pandas dataframe groupby 选择列

python - 如何使用 Python 绘制能量排名图?