使用 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 计算),我得到这样的结果:
为了更轻松地将图例项与重叠圆圈的混合颜色进行比较,我将图例项用 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/