I am testing the clip_box feature of Artist using the code snippet below:
import matplotlib.pyplot as plt
from matplotlib.transforms import Bbox
import numpy as np
fig = plt.figure()
ax = fig.subplots(1, 2)
x = [1, 2, 3, 4]
y = [3, 8, 5, 2]
line_a, = ax[0].plot(x, y, color='red', linewidth=3.0)
line_b, = ax[1].plot(x, y, color='red', linewidth=3.0)
boundingbox = Bbox(np.array([[0, 0], [3, 9]]))
line_b.set_clip_box(boundingbox)
line_b.set_clip_on(True)
plt.show()
What I expect is the last part of line_b will be cut out by the clip box, and line_b will be a bit shorter than line_a.
It turns out that there's nothing left on the second subplot. It's totally empty. Is my understanding of the clip_box wrong or are there some issues in the code snippet?
The "natural" clip box for the right hand side plot is ax[1].bbox. Finding its extent tells us what units should be used to specify the clip box Bbox.
Since we don't add the Bbox instance to any axes when we create, it could only be relative to the figure. When we print ax[1].bbox, we can see that its size is to be specified in pixels.
It's indeed much simpler to use a Rectangle or Polygon to specify the clip box because they can be added to axes. Using 'none' color for its facecolor could be more convenient because it's figure style-independent.
import matplotlib.pyplot as plt
from matplotlib.transforms import Bbox
fig = plt.figure(dpi=89)
ax = fig.subplots(1, 2)
x = [1, 2, 3, 4]
y = [3, 8, 5, 2]
line_a, = ax[0].plot(x, y, color='red', linewidth=3.0)
line_b, = ax[1].plot(x, y, color='red', linewidth=3.0)
print(ax[1].bbox, '\n', ax[1].bbox.extents)
# the line above prints
# TransformedBbox(
# Bbox(x0=0.5477272727272726, y0=0.10999999999999999, x1=0.8999999999999999, y1=0.88),
# BboxTransformTo(
# TransformedBbox(
# Bbox(x0=0.0, y0=0.0, x1=6.393258426966292, y1=4.797752808988764),
# Affine2D().scale(178.0))))
# [ 623.31363636 93.94 1024.2 751.52 ]
# 178.0 is 2 * dpi, I believe the doubling happens because of what screen I have got
boundingbox = Bbox.from_extents([623.31363636, 93.94, 900.2, 751.52])
print(boundingbox, '\n', boundingbox.extents)
# the line above prints
# Bbox(x0=623.31363636, y0=93.94, x1=900.2, y1=751.52)
# [623.31363636 93.94 900.2 751.52 ]
line_b.set_clip_box(boundingbox)
line_b.set_clip_on(True)
plt.show()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With