Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit ea082aa

Browse filesBrowse files
committed
Clipping for OffsetBoxes
- Child `Artists` of `DrawingArea` can now get clipped to the bounds of the parent
1 parent fce2a6d commit ea082aa
Copy full SHA for ea082aa

File tree

Expand file treeCollapse file tree

10 files changed

+328
-4
lines changed
Filter options
Expand file treeCollapse file tree

10 files changed

+328
-4
lines changed
+8Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'OffsetBox.DrawingArea' respects 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 on a per-child basis using `child.set_clip_on(False)`.

‎doc/users/whats_new/offsetbox.rst

Copy file name to clipboard
+11Lines 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` can be
11+
clipped to the bounds of the `DrawingArea`.

‎examples/pylab_examples/anchored_artists.py

Copy file name to clipboardExpand all lines: examples/pylab_examples/anchored_artists.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class AnchoredDrawingArea(AnchoredOffsetbox):
6363
def __init__(self, width, height, xdescent, ydescent,
6464
loc, pad=0.4, borderpad=0.5, prop=None, frameon=True):
6565

66-
self.da = DrawingArea(width, height, xdescent, ydescent, clip=True)
66+
self.da = DrawingArea(width, height, xdescent, ydescent)
6767

6868
super(AnchoredDrawingArea, self).__init__(loc, pad=pad, borderpad=borderpad,
6969
child=self.da,

‎lib/matplotlib/__init__.py

Copy file name to clipboardExpand all lines: lib/matplotlib/__init__.py
+1Lines 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

Copy file name to clipboardExpand all lines: lib/matplotlib/offsetbox.py
+16-2Lines changed: 16 additions & 2 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

@@ -569,14 +570,16 @@ class DrawingArea(OffsetBox):
569570
"""
570571
The DrawingArea can contain any Artist as a child. The DrawingArea
571572
has a fixed width and height. The position of children relative to
572-
the parent is fixed.
573+
the parent is fixed. The children can be clipped at the
574+
boundaries of the parent.
573575
"""
574576

575577
def __init__(self, width, height, xdescent=0.,
576-
ydescent=0., clip=True):
578+
ydescent=0., clip=False):
577579
"""
578580
*width*, *height* : width and height of the container box.
579581
*xdescent*, *ydescent* : descent of the box in x- and y-direction.
582+
*clip* : Whether to clip the children
580583
"""
581584

582585
super(DrawingArea, self).__init__()
@@ -585,6 +588,7 @@ def __init__(self, width, height, xdescent=0.,
585588
self.height = height
586589
self.xdescent = xdescent
587590
self.ydescent = ydescent
591+
self._clip_children = clip
588592

589593
self.offset_transform = mtransforms.Affine2D()
590594
self.offset_transform.clear()
@@ -656,7 +660,17 @@ def draw(self, renderer):
656660
self.dpi_transform.clear()
657661
self.dpi_transform.scale(dpi_cor, dpi_cor)
658662

663+
# At this point the DrawingArea has a transform
664+
# to the display space so the path created is
665+
# good for clipping children
666+
tpath = mtransforms.TransformedPath(
667+
mpath.Path([[0, 0], [0, self.height],
668+
[self.width, self.height],
669+
[self.width, 0]]),
670+
self.get_transform())
659671
for c in self._children:
672+
if self._clip_children and not (c.clipbox or c._clippath):
673+
c.set_clip_path(tpath)
660674
c.draw(renderer)
661675

662676
bbox_artist(self, renderer, fill=False, props=dict(pad=0.))
Binary file not shown.
Loading
+241Lines changed: 241 additions & 0 deletions
Loading
+49Lines 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, clip=True)
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

Copy file name to clipboardExpand all lines: lib/mpl_toolkits/axes_grid1/anchored_artists.py
+1-1Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.