[Matplotlib-devel] Masking in Matplotlib - Resetting the zorder of all pixels depending on their color value ?

Hello Matplotlib Developers!

  1. Matplotlib has a Clipping capability, but the “clipped” out areas use the same zorder,

therefore rendering several overlapping polygonal shapes visible based on their zorder

does not work in the areas where clipping was used to render one of them.

  1. If it were possible to “reset” the zorder of a given pixel color (our background color) at any time while rendering, then we would have resolved

the issue with clipping. We would not even need clipping as we could just use a given zorder value for the parts that define our desired mask areas,

and a lower zorder for the part to be clipped, and after rendering the part in question, we change the zorder of all the “white” pixels to a low

zorder value, and we have the masking capability working !

If this is not possible with the current version of Matplotlib, please can you help me giving me the code needed ?

Example for illustration (see attached snapshot figure):

‘’'Example of two overlapping squares having arbitrary openings in them.

In this example the opening is just two smaller overlapping square, but it can be anything.

We want to paint the green and red squares so that we see what is behind the opening(s)’’’

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(6, 6))

This is to test if a well ordered polygon with slits (to define holes) can be rendered

quad_small = [(-0.2, -0.2), (-0.2, 0.2), (0.2, 0.2), (0.2, -0.2), (-0.2, -0.2)]

quad1x1 = [(-1, 1.), (-1, -1.), (1, -1.), (1., 1.), (-1, 1.)]

#Fill quad1x1 with green

x11 = [coord[0] for coord in quad1x1]

y11 = [coord[1] for coord in quad1x1]

plt.fill(x11, y11, facecolor=‘green’, zorder=5)

‘’'Now make one or more holes, possibly overlapping holes,

NOTE: if we use clipping to define the holes, Matplotlib sets the same zorder over all the clippped areas

which was used. Also clipping does not work well with overlapping small squares. Would only work with nonoverlapping

squares.’’’

xsq = [coord[0] for coord in quad_small]

ysq = [coord[1] for coord in quad_small]

plt.fill(xsq, ysq, facecolor=‘white’, zorder=5)

xsq = [coord[0]+0.2 for coord in quad_small]

ysq = [coord[1]+0.2 for coord in quad_small]

plt.fill(xsq, ysq, facecolor=‘white’, zorder=5)

‘’'At this point green and white openings have the same zorder=5.

We would need a call to change the zorder of all the ‘white’ pixels to a lower value, say 3’’’

‘’'Now we want to render another polygon (red) with holes, but ONLY on areas not covered by the previous rendering,

we use a lower zorder so that we do not paint on the green part’’’

x11 = [coord[0]+0.3 for coord in quad1x1]

y11 = [coord[1]+0.3 for coord in quad1x1]

plt.fill(x11, y11, facecolor=‘red’, zorder=4)

xsq = [coord[0]+0.3 for coord in quad_small]

ysq = [coord[1]+0.3 for coord in quad_small]

plt.fill(xsq, ysq, facecolor=‘white’, zorder=4)

xsq = [coord[0]+0.5 for coord in quad_small]

ysq = [coord[1]+0.5 for coord in quad_small]

plt.fill(xsq, ysq, facecolor=‘white’, zorder=4)

‘’‘The hole (white area) of the green square is not painted in red because the zorder of the white area is higher’’’

plt.show()

squares.gif

···

Schlumberger-Private

You used a single square to define the opening !

Try with the hole defined with “overlapping quads” as I used in my original example, and look at what happens in the area defined by the overlapping
little quads.

Schlumberger-Private

···

From: Elan Ernest elch.rz@ruetz-online.de
Sent: Monday, September 23, 2019 12:55 PM
To: Carlos Baumann CBaumann@slb.com; matplotlib-devel@python.org
Subject: [Ext] Re: [Matplotlib-devel] Masking in Matplotlib - Resetting the zorder of all pixels depending on their color value ?

Xref:
https://stackoverflow.com/questions/58053011/matplotlib-masking-resetting-the-zorder-of-pixels-depending-on-their-current-c

I gave an answer over there.

Am 23.09.2019 um 19:12 schrieb Carlos Baumann via Matplotlib-devel:

Hello Matplotlib Developers!

  1. Matplotlib has a Clipping capability, but the “clipped” out areas use the same zorder,

therefore rendering several overlapping polygonal shapes visible based on their zorder

does not work in the areas where clipping was used to render one of them.

  1. If it were possible to “reset” the zorder of a given pixel color (our background color) at any time while rendering, then we would have resolved

the issue with clipping. We would not even need clipping as we could just use a given zorder value for the parts that define our desired mask areas,

and a lower zorder for the part to be clipped, and after rendering the part in question, we change the zorder of all the “white” pixels to a low

zorder value, and we have the masking capability working !

If this is not possible with the current version of Matplotlib, please can you help me giving me the code needed ?

Example for illustration (see attached snapshot figure):

‘’'Example of two overlapping squares having arbitrary openings in them.

In this example the opening is just two smaller overlapping square, but it can be anything.

We want to paint the green and red squares so that we see what is behind the opening(s)‘’’

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(6, 6))

This is to test if a well ordered polygon with slits (to define holes) can be rendered

quad_small = [(-0.2, -0.2), (-0.2, 0.2), (0.2, 0.2), (0.2, -0.2), (-0.2, -0.2)]

quad1x1 = [(-1, 1.), (-1, -1.), (1, -1.), (1., 1.), (-1, 1.)]

#Fill quad1x1 with green

x11 = [coord[0] for coord in quad1x1]

y11 = [coord[1] for coord in quad1x1]

plt.fill(x11, y11, facecolor=‘green’, zorder=5)

‘’'Now make one or more holes, possibly overlapping holes,

NOTE: if we use clipping to define the holes, Matplotlib sets the same zorder over all the clippped areas

which was used. Also clipping does not work well with overlapping small squares. Would only work with nonoverlapping

squares.‘’’

xsq = [coord[0] for coord in quad_small]

ysq = [coord[1] for coord in quad_small]

plt.fill(xsq, ysq, facecolor=‘white’, zorder=5)

xsq = [coord[0]+0.2 for coord in quad_small]

ysq = [coord[1]+0.2 for coord in quad_small]

plt.fill(xsq, ysq, facecolor=‘white’, zorder=5)

‘’'At this point green and white openings have the same zorder=5.

We would need a call to change the zorder of all the ‘white’ pixels to a lower value, say 3’‘’

‘’'Now we want to render another polygon (red) with holes, but ONLY on areas not covered by the previous rendering,

we use a lower zorder so that we do not paint on the green part’‘’

x11 = [coord[0]+0.3 for coord in quad1x1]

y11 = [coord[1]+0.3 for coord in quad1x1]

plt.fill(x11, y11, facecolor=‘red’, zorder=4)

xsq = [coord[0]+0.3 for coord in quad_small]

ysq = [coord[1]+0.3 for coord in quad_small]

plt.fill(xsq, ysq, facecolor=‘white’, zorder=4)

xsq = [coord[0]+0.5 for coord in quad_small]

ysq = [coord[1]+0.5 for coord in quad_small]

plt.fill(xsq, ysq, facecolor=‘white’, zorder=4)

‘’‘The hole (white area) of the green square is not painted in red because the zorder of the white area is higher’‘’

plt.show()

Schlumberger-Private

_______________________________________________
Matplotlib-devel mailing list
Matplotlib-devel@python.org
[https://mail.python.org/mailman/listinfo/matplotlib-devel](https://urldefense.proofpoint.com/v2/url?u=https-3A__mail.python.org_mailman_listinfo_matplotlib-2Ddevel&d=DwMD-g&c=CRKael6LgVt5xjvyqPD27dPR2eKsAMw5_UGvkEk3eUY&r=caVwniZ_hqqspMDKXHctWw&m=6ERDdhz-3vALl5JuSjEaKIFax2iK_eSZ-SPXAGNK6pk&s=XjEpAY7KQqKhQN8fMGlrnKzC4GY9x2S-zgCPpuiVI3A&e=)

Xref:

I gave an answer over there.

···

https://stackoverflow.com/questions/58053011/matplotlib-masking-resetting-the-zorder-of-pixels-depending-on-their-current-c
Am 23.09.2019 um 19:12 schrieb Carlos
Baumann via Matplotlib-devel:

Hello Matplotlib Developers!

      1) Matplotlib has a Clipping capability,

but the “clipped” out areas use the same zorder,

      therefore rendering several overlapping

polygonal shapes visible based on their zorder

      does not work in the areas where clipping

was used to render one of them.

      2) If it were possible to "reset" the

zorder of a given pixel color (our background color) at any
time while rendering, then we would have resolved

      the issue with clipping. We would not even

need clipping as we could just use a given zorder value for
the parts that define our desired mask areas,

      and a lower zorder for the part to be

clipped, and after rendering the part in question, we change
the zorder of all the “white” pixels to a low

      zorder value, and we have the masking

capability working !

      If this is not possible with the current

version of Matplotlib, please can you help me giving me the
code needed ?

      Example for illustration (see attached

snapshot figure):

      '''Example of two overlapping squares

having arbitrary openings in them.

      In this example the opening is just two

smaller overlapping square, but it can be anything.

      We want to paint the green and red squares

so that we see what is behind the opening(s)‘’’

import matplotlib.pyplot as plt

fig, ax = plt.subplots(figsize=(6, 6))

      # This is to test if a well ordered polygon

with slits (to define holes) can be rendered

      quad_small = [(-0.2, -0.2), (-0.2, 0.2),

(0.2, 0.2), (0.2, -0.2), (-0.2, -0.2)]

      quad1x1 = [(-1, 1.), (-1, -1.), (1, -1.),

(1., 1.), (-1, 1.)]

#Fill quad1x1 with green

x11 = [coord[0] for coord in quad1x1]

y11 = [coord[1] for coord in quad1x1]

      plt.fill(x11, y11, facecolor='green',

zorder=5)

      '''Now make one or more holes, possibly

overlapping holes,

      NOTE: if we use clipping to define the

holes, Matplotlib sets the same zorder over all the clippped
areas

      which was used. Also clipping does not work

well with overlapping small squares. Would only work with
nonoverlapping

squares.‘’’

xsq = [coord[0] for coord in quad_small]

ysq = [coord[1] for coord in quad_small]

      plt.fill(xsq, ysq, facecolor='white',

zorder=5)

      xsq = [coord[0]+0.2 for coord in

quad_small]

      ysq = [coord[1]+0.2 for coord in

quad_small]

      plt.fill(xsq, ysq, facecolor='white',

zorder=5)

      '''At this point green and white openings

have the same zorder=5.

      We would need a call to change the zorder

of all the ‘white’ pixels to a lower value, say 3’‘’

      '''Now we want to render another polygon

(red) with holes, but ONLY on areas not covered by the
previous rendering,

      we use a lower zorder so that we do not

paint on the green part’‘’

x11 = [coord[0]+0.3 for coord in quad1x1]

y11 = [coord[1]+0.3 for coord in quad1x1]

      plt.fill(x11, y11, facecolor='red',

zorder=4)

      xsq = [coord[0]+0.3 for coord in

quad_small]

      ysq = [coord[1]+0.3 for coord in

quad_small]

      plt.fill(xsq, ysq, facecolor='white',

zorder=4)

      xsq = [coord[0]+0.5 for coord in

quad_small]

      ysq = [coord[1]+0.5 for coord in

quad_small]

      plt.fill(xsq, ysq, facecolor='white',

zorder=4)

      '''The hole (white area) of the green

square is not painted in red because the zorder of the white
area is higher’‘’

plt.show()

Schlumberger-Private

_______________________________________________
Matplotlib-devel mailing list

Matplotlib-devel@python.orghttps://mail.python.org/mailman/listinfo/matplotlib-devel