8

I would like to add a rectangle over a graph. Through all the documentation I've found, the rectangle should be opaque by default, with transparency controlled by an alpha argument. However, I can't get the rectangle to show up as opaque, even with alpha = 1. Am I doing something wrong, or is there something else I need to know about the way that graphs interact with patches?

Here is a toy example:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.patches as patches
from pylab import *

x = np.arange(10)
y = x
fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(x, y)

rect = patches.Rectangle( ( 2,3 ), 2, 2, alpha = 1, ec = "gray", fc = "CornflowerBlue", visible = True)
ax.add_patch(rect)

plt.show()

2 Answers2

11

From the documentation:

Within an axes, the order that the various lines, markers, text, collections, etc appear is determined by the matplotlib.artist.Artist.set_zorder() property. The default order is patches, lines, text, with collections of lines and collections of patches appearing at the same level as regular lines and patches, respectively.

So patches will be drawn below lines by default. You can change the order by specifying the zorder of the rectangle:

# note alpha is None and visible is True by default
rect = patches.Rectangle((2, 3), 2, 2, ec="gray", fc="CornflowerBlue", zorder=10)

You can check the zorder of the line on your plot by changing ax.plot(x, y) to lines = ax.plot(x, y) and add a new line of code: print lines[0].zorder. When I did this, the zorder for the line was 2. Therefore, the rectangle will need a zorder > 2 to obscure the line.

Gary Kerr
  • 13,650
  • 4
  • 48
  • 51
  • Aha! That explains it. Setting a higher zorder for the rectangle than for the line fixed the apparent transparency. Thank you so much for your answer and explanation. –  Mar 22 '11 at 12:51
0

Your choice of facecolor (CornflowerBlue) has an appearance of being semi-opaque, but in reality the color you are seeing is correct for alpha = 1. Try a different color like 'blue' instead. Matplotlib does appear to be placing the rectangular patch below the line, but I don't think that's a transparency issue.

JoshAdel
  • 66,734
  • 27
  • 141
  • 140
  • Using 'blue' did make the rectangle look opaque, but it was because it blended in with the line. When I tried 'red' and other more basic colors it was clear that my color choice was not causing the apparent transparency issue. You are correct that Matplotlib was placing the line above the rectangular patch, that turned out to be the issue :) –  Mar 22 '11 at 18:33