1

The alpha levels are increased where the points overlap, so the darkest areas are where points are overlapping.

I would instead like the alpha levels to subtract from each other somehow - so that if there was an overlapping section it would be lighter than a section with no overlap.

Here is an example of what I mean - from left to right the points become darker as there are more overlapped:

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(20, 3))

# X and Y coordinates for red circles
red_xs = [1]
red_ys = [1]

# Plot with a large markersize
markersize = 35
alpha = 0.1

for i in range(20):
    red_xs[0] += 1
    for add in range(i):
        ax.plot(
            red_xs,
            red_ys,
            marker="o",
            color="r",
            linestyle="",
            markersize=markersize,
            alpha=alpha,
        )

which looks as: enter image description here

I would like the inverse of this - to be able to start with an alpha level of the point on the far right and for the point to be come fainter in the areas that overlap, which would have the result of rendering as the point in the far left as many are overlayed.

To give a more concrete example where points are no perfectly overlayed:

import matplotlib.pyplot as plt
import random

fig, ax = plt.subplots(figsize=(20, 3))

# X and Y coordinates for red circles
red_xs = [1]
red_ys = [1]

# Plot with a large markersize
markersize = 35
alpha = 0.01

random.seed(1)
for j in range(5):
    red_xs = [1]
    red_ys = [1]

    for i in range(20):
        u = 0.1
        v = 0.00000001
        dx = random.uniform(-u, u)
        dy = random.uniform(-u, u)
        red_xs[0] += 2 + dx
        red_ys[0] += dy
        for add in range(i):
            ax.plot(
                red_xs,
                red_ys,
                marker="o",
                color="r",
                linestyle="",
                markersize=markersize,
                alpha=alpha,
            )

looks as:

enter image description here

For parts where there are overlapping points such as these:

enter image description here

The solution should render y (where they intersect) the alpha of x, and x the alpha of y. And this should work for any number of layers.

baxx
  • 3,956
  • 6
  • 37
  • 75
  • 1
    Check https://stackoverflow.com/questions/26702176/is-it-possible-to-do-additive-blending-with-matplotlib – ImportanceOfBeingErnest May 04 '20 at 09:04
  • @ImportanceOfBeingErnest interesting - seems to be about mixing colours though, whereas my question is about having alpha levels reduce as points are overlaid. – baxx May 04 '20 at 11:14
  • 1
    At the ends it's all about blending colors (The A-channel in RGBA color). Also see [this comment](https://stackoverflow.com/questions/50285019/possible-to-render-points-plotted-in-python-with-matplotlib-using-a-blending-mod#comment87626783_50285019). I'm not saying there is a ready-to-use answer, but those things may allow you to advance on that problem. – ImportanceOfBeingErnest May 04 '20 at 23:54

1 Answers1

0

What if you invert all colors and then invert only the background? (Or perhaps just invert the background - i.e. make the background black and then invert all colors). The reason this might work is that the formula for the color at any given location can be determined as follows:

  1. Define N(x,y) - This is the multiplicity at any given coordinate. 0 = no points, 1 = one point, 2 = 2 overlapping points, etc..
  2. Alpha(x,y) = 1 - (1 - alpha)^N(x,y); This is how to combine opaque objects.

Now the problem with what you are searching for is that it is a non-linear outcome. I have some more suggestions included below, but if you are simply trying to solve a problem, I'd suggest you use a custom colormap instead of points because it would allow you to have more control and customization, as well as solve this in a self-contained matplotlib-only approach.

If you could take all of the TRUE white-space and make it red (alpha = 1.0), you could then swap red and white to get the effect you are desiring. The difficulty is that alpha yields a mix of the background and the point's color, so inversion needs the TRUE white-space to match the foreground color (red here) in order to invert the foreground and background. You'd have to save the plot as an image and then invert the colors. This solution would work exactly how you are hoping for, but it isn't a matplotlib ONLY solution unfortunately.

Blue Robin
  • 847
  • 2
  • 11
  • 31