0

What is the best solution for highlighting an area in a contourf plot? I want the background to be opacity of 0.5 and the user chosen area to be normal. How can I achieve this?

J CB
  • 25
  • 4

1 Answers1

1

In How to nicely plot clipped layered artists in matplotlib? Jake Vanderplas shows a way to draw a rectangle with a rectangular hole. The code can be adapted for your situation. The following example starts from a tutorial example, and highlights the third contour:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.path import Path
from matplotlib.patches import PathPatch

def DoubleRect(xy1, width1, height1,
               xy2, width2, height2, **kwargs):
    base = np.array([(0, 0), (0, 1), (1, 1), (1, 0), (0, 0)])
    verts = np.vstack([xy1 + (width1, height1) * base,
                       xy2 + (width2, height2) * base[::-1],
                       xy1])
    codes = 2 * ([Path.MOVETO] + 4 * [Path.LINETO]) + [Path.CLOSEPOLY]
    return PathPatch(Path(verts, codes), **kwargs)

origin = 'lower'
delta = 0.025
x = y = np.arange(-3.0, 3.01, delta)
X, Y = np.meshgrid(x, y)
Z1 = np.exp(-X ** 2 - Y ** 2)
Z2 = np.exp(-(X - 1) ** 2 - (Y - 1) ** 2)
Z = (Z1 - Z2) * 2

fig, ax = plt.subplots()
contours = ax.contourf(X, Y, Z, 10, cmap=plt.cm.turbo, origin=origin)
# contours.collections[2].set_color('deepskyblue') # mark one contour

# calculate (or get) the coordinates of the hole
bbox = contours.collections[2].get_paths()[0].get_extents()
hole_xy, hole_width, hole_height = bbox.p0, bbox.width, bbox.height

# find the coordinates of the surrounding rectangle
xmin, xmax = ax.get_xlim()
ymin, ymax = ax.get_ylim()
full_rect = plt.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, color='black', alpha=0.5)
ax.add_patch(full_rect)

# create a rectangle with a hole to clip the surrounding rectangle
mask = DoubleRect((xmin, ymin), xmax - xmin, ymax - ymin,
                  hole_xy, hole_width, hole_height,
                  facecolor='none', edgecolor='none')
ax.add_patch(mask)
full_rect.set_clip_path(mask)

plt.show()

Instead of darkening the outside region, it could also be hatched (similar to the linked post). This would set the edge color of the mask to 'black', and create the full rectangle with hatching.

full_rect = plt.Rectangle((xmin, ymin), xmax - xmin, ymax - ymin, facecolor='none', edgecolor='black', hatch='//')

plt.contourf with one highlighted area

JohanC
  • 71,591
  • 8
  • 33
  • 66
  • Sry was my bad: What I want is to highlight a rectangular area of the contour plot, not a certain level! My solution atm ist to just plot the area with contourf(Xare,Yarea,Zarea) over the original plot. May problems are usually performance problems as i need lots of levels for my paper :( – J CB Aug 18 '21 at 14:54
  • yesssss! That's perfect and it seems I can use blitting, which helps me in terms of performance. Thank you very much and greetings from Germany! – J CB Aug 19 '21 at 17:33