Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ff44733

Browse files
committed
Clipping for OffsetBoxes
- Child `Artists` of `DrawingArea` now get clipped to the bounds of the parent
1 parent f3bf9a8 commit ff44733

File tree

9 files changed

+325
-8
lines changed

9 files changed

+325
-8
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'OffsetBox.DrawingArea' no longer accepts the 'clip' keyword argument
2+
`````````````````````````````````````````````````````````````````````
3+
4+
The call signature was `OffsetBox.DrawingArea(..., clip=True)` but nothing
5+
was done with the `clip` argument. The object did not do any clipping
6+
regardless of that parameter. Now the object can and does clip the child `Artists` if they are set to be clipped.
7+
8+
You can turn off the clipping using :method:`Artist.set_clip_on(False)`

doc/users/whats_new/offsetbox.rst

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
OffsetBoxes now support clipping
2+
````````````````````````````````
3+
4+
`Artists` draw onto objects of type :class:`~OffsetBox`
5+
through :class:`~OffsetBox.DrawingArea` and :class:`~OffsetBox.TextArea`.
6+
The `TextArea` calculates the required space for the text and so the
7+
text is always within the bounds, for this nothing has changed.
8+
9+
However, `DrawingArea` acts as a parent for zero or more `Artists` that
10+
draw on it and may do so beyond the bounds. Now child `Artists` are by
11+
default clipped to the bounds of the `DrawingArea`.

lib/matplotlib/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,7 @@ def tk_window_focus():
14161416
'matplotlib.tests.test_lines',
14171417
'matplotlib.tests.test_mathtext',
14181418
'matplotlib.tests.test_mlab',
1419+
'matplotlib.tests.test_offsetbox',
14191420
'matplotlib.tests.test_patches',
14201421
'matplotlib.tests.test_path',
14211422
'matplotlib.tests.test_patheffects',

lib/matplotlib/offsetbox.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import matplotlib.transforms as mtransforms
2525
import matplotlib.artist as martist
2626
import matplotlib.text as mtext
27+
import matplotlib.path as mpath
2728
import numpy as np
2829
from matplotlib.transforms import Bbox, BboxBase, TransformedBbox
2930

@@ -149,11 +150,6 @@ def __init__(self, *args, **kwargs):
149150

150151
super(OffsetBox, self).__init__(*args, **kwargs)
151152

152-
# Clipping has not been implemented in the OffesetBox family, so
153-
# disable the clip flag for consistency. It can always be turned back
154-
# on to zero effect.
155-
self.set_clip_on(False)
156-
157153
self._children = []
158154
self._offset = (0, 0)
159155

@@ -562,11 +558,12 @@ class DrawingArea(OffsetBox):
562558
"""
563559
The DrawingArea can contain any Artist as a child. The DrawingArea
564560
has a fixed width and height. The position of children relative to
565-
the parent is fixed.
561+
the parent is fixed. By default the children are clipped at the
562+
boundaries of the parent.
566563
"""
567564

568565
def __init__(self, width, height, xdescent=0.,
569-
ydescent=0., clip=True):
566+
ydescent=0.):
570567
"""
571568
*width*, *height* : width and height of the container box.
572569
*xdescent*, *ydescent* : descent of the box in x- and y-direction.
@@ -648,7 +645,17 @@ def draw(self, renderer):
648645
self.dpi_transform.clear()
649646
self.dpi_transform.scale(dpi_cor, dpi_cor)
650647

648+
# At this point the DrawingArea has a transform
649+
# to the display space so the path created is
650+
# good for clipping children
651+
tpath = mtransforms.TransformedPath(
652+
mpath.Path([[0, 0], [0, self.height],
653+
[self.width, self.height],
654+
[self.width, 0]]),
655+
self.get_transform())
651656
for c in self._children:
657+
if not c.clipbox and not c._clippath:
658+
c.set_clip_path(tpath)
652659
c.draw(renderer)
653660

654661
bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
Binary file not shown.
Lines changed: 241 additions & 0 deletions
Loading
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from __future__ import (absolute_import, division, print_function,
2+
unicode_literals)
3+
4+
import nose
5+
6+
from matplotlib.testing.decorators import image_comparison
7+
import matplotlib.pyplot as plt
8+
import matplotlib.patches as mpatches
9+
import matplotlib.lines as mlines
10+
from matplotlib.offsetbox import AnchoredOffsetbox, DrawingArea
11+
12+
13+
@image_comparison(baseline_images=['offsetbox_clipping'], remove_text=True)
14+
def test_offsetbox_clipping():
15+
# - create a plot
16+
# - put an AnchoredOffsetbox with a child DrawingArea
17+
# at the center of the axes
18+
# - give the DrawingArea a gray background
19+
# - put a black line across the bounds of the DrawingArea
20+
# - see that the black line is clipped to the edges of
21+
# the DrawingArea.
22+
fig, ax = plt.subplots()
23+
size = 100
24+
da = DrawingArea(size, size)
25+
bg = mpatches.Rectangle((0, 0), size, size,
26+
facecolor='#CCCCCC',
27+
edgecolor='None',
28+
linewidth=0)
29+
line = mlines.Line2D([-size*.5, size*1.5], [size/2, size/2],
30+
color='black',
31+
linewidth=10)
32+
anchored_box = AnchoredOffsetbox(
33+
loc=10,
34+
child=da,
35+
pad=0.,
36+
frameon=False,
37+
bbox_to_anchor=(.5, .5),
38+
bbox_transform=ax.transAxes,
39+
borderpad=0.)
40+
41+
da.add_artist(bg)
42+
da.add_artist(line)
43+
ax.add_artist(anchored_box)
44+
ax.set_xlim((0, 1))
45+
ax.set_ylim((0, 1))
46+
47+
48+
if __name__ == '__main__':
49+
nose.runmodule(argv=['-s', '--with-doctest'], exit=False)

lib/mpl_toolkits/axes_grid1/anchored_artists.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def __init__(self, width, height, xdescent, ydescent,
2424
*prop* : font property. This is only used for scaling the paddings.
2525
"""
2626

27-
self.da = DrawingArea(width, height, xdescent, ydescent, clip=True)
27+
self.da = DrawingArea(width, height, xdescent, ydescent)
2828
self.drawing_area = self.da
2929

3030
super(AnchoredDrawingArea, self).__init__(loc, pad=pad, borderpad=borderpad,

0 commit comments

Comments
 (0)