How does 'alpha' in matplotlib work with respect to zorder, and how can one blend colors symmetrically?

Viewed 536

So, I've been messing around with matplotlib and found out this. If I plot different symbols atop each other with alpha less than 1:

kwdict_plot={
    'marker':'o', 
    'markersize':70,
    'alpha':0.6,
    'markeredgewidth':0,
}

fig, ax = plt.subplots(1,2, figsize=(6,3))
ax[0].plot([ sqrt(3/4)],[-0.5], color='r', **kwdict_plot)
ax[0].plot([         0],[ 1  ], color='g', **kwdict_plot)
ax[0].plot([-sqrt(3/4)],[-0.5], color='b', **kwdict_plot)
ax[0].set_xlim([-3,3])
ax[0].set_ylim([-3,3])
ax[0].set_aspect('equal')
ax[0].set_title('r->g->b')
ax[1].plot([-sqrt(3/4)],[-0.5], color='b', **kwdict_plot)
ax[1].plot([         0],[ 1  ], color='g', **kwdict_plot)
ax[1].plot([ sqrt(3/4)],[-0.5], color='r', **kwdict_plot)
ax[1].set_xlim([-3,3])
ax[1].set_ylim([-3,3])
ax[1].set_aspect('equal')
ax[1].set_title('b->g->r')
fig.tight_layout()

Then the final color seems to be affected by the order with which symbols are drawn.

See the code above

I always believed that alpha channel represents the transparency that it would act as an multiplicative operation on the spectrum it transmits. Just like simulating the cellophane papers or colored filters with different colors. Apparently this seems not the case in matplotlib.

So, how does it work actually? And how can I get the colors mixed symmetrically?

1 Answers

According to here, when zorder is used with alpha, the colors are updated as follows:

RGB = RGBold * (1 - alpha) + RGBnew * alpha

where RGBnew is whichever color has higher zorder, and RGBold is the one with lower zorder, and alpha belongs to RGBnew. I believe the white background counts as the lowest layer, so where two circles overlap, there are three colors being mixed. On the left, for example, we have a region with green over red over white, which becomes

RGB1 = white * 0.4 + red * 0.6
RGB2 = (RGB1) * (0.4) + (green) * 0.6 = red * 0.24 + green * 0.6

On the right, the same region instead is red over green over white, producing

RGB2 = green * 0.24 + red * 0.6

If you want the two regions where green overlaps with red to be the same, then you won't be able to choose the same alpha for both colors in both cases -- the green will have to be weaker than red in the first case, and v.v. for the second, to offset the imbalance created by compounding the alphas. You could choose 0.6 for red (left) and green (right), and then 0.375 for green (left) and red (right).

Related