8000 added subplot params and toolbar · matplotlib/matplotlib@fa318da · GitHub
[go: up one dir, main page]

Skip to content

Commit fa318da

Browse files
committed
added subplot params and toolbar
svn path=/trunk/matplotlib/; revision=1442
1 parent d66e9b9 commit fa318da

13 files changed

+400
-21
lines changed

.matplotlibrc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,18 @@ figure.dpi : 80 # figure dots per inch
167167
figure.facecolor : 0.75 # figure facecolor; 0.75 is scalar gray
168168
figure.edgecolor : white # figure edgecolor
169169

170+
# The figure subplot parameters. All dimensions are fraction of the
171+
# figure width or height
172+
figure.subplot.left : 0.125 # the left side of the subplots of the figure
173+
figure.subplot.right : 0.9 # the right side of the subplots of the figure
174+
figure.subplot.bottom : 0.1 # the bottom of the subplots of the figure
175+
figure.subplot.top : 0.9 # the top of the subplots of the figure
176+
figure.subplot.wspace : 0.2 # the amount of width reserved for blank space between subplots
177+
figure.subplot.hspace : 0.2 # the amount of height reserved for white space between subplots
178+
179+
180+
181+
170182
### images
171183
image.aspect : free # free | preserve
172184
image.interpolation : bilinear # see help(imshow) for options

CHANGELOG

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
New entries should be added at the top
22

3+
2005-06-14 Exposed subplot parameters as rc vars and as the fig
4+
SubplotParams instance subplotpars. See
5+
figure.SubplotParams, figure.Figure.subplots_adjust and the
6+
pylab method subplots_adjust and
7+
examples/subplots_adjust.py . Also added a GUI neutral
8+
widget for adjusting subplots, see
9+
examples/subplot_toolbar.py - JDH
10+
311
2005-06-13 Exposed cap and join style for lines with new rc params and
412
line properties
513

examples/major_minor_demo1.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@
2424
grid of the minor ticks for a given axis, use for example
2525
2626
ax.xaxis.grid(True, which='minor')
27+
28+
Note, you should not use the same locator between different Axis
29+
because the locator stores references to the Axis data and view limits
30+
2731
"""
2832

2933
from pylab import *

examples/subplot_toolbar.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from pylab import *
2+
3+
fig = figure()
4+
subplot(221)
5+
imshow(rand(100,100))
6+
subplot(222)
7+
imshow(rand(100,100))
8+
subplot(223)
9+
imshow(rand(100,100))
10+
subplot(224)
11+
imshow(rand(100,100))
12+
13+
subplot_tool()
14+
show()

examples/subplots_adjust.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
from pylab import *
2+
3+
4+
subplot(211)
5+
imshow(rand(100,100))
6+
subplot(212)
7+
imshow(rand(100,100))
8+
9+
subplots_adjust(bottom=0.1, right=0.8, top=0.9)
10+
cax = axes([0.85, 0.1, 0.075, 0.8])
11+
colorbar(cax=cax)
12+
show()

lib/matplotlib/__init__.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,36 @@ def validate_verbose_fileo(s):
475475
validate_joinstyle = ValidateInStrings(['miter', 'round', 'bevel'], ignorecase=True)
476476

477477
validate_capstyle = ValidateInStrings(['butt', 'round', 'projecting'], ignorecase=True)
478+
479+
480+
class ValidateInterval:
481+
"""
482+
Value must be in interval
483+
"""
484+
def __init__(self, vmin, vmax, closedmin=True, closedmax=True):
485+
self.vmin = vmin
486+
self.vmax = vmax
487+
self.cmin = closedmin
488+
self.cmax = closedmax
489+
490+
def __call__(self, s):
491+
try: s = float(s)
492+
except: raise RuntimeError('Value must be a float; found "%s"'%s)
493+
494+
if self.cmin and s<self.vmin:
495+
raise RuntimeError('Value must be >= %f; found "%f"'%(self.vmin, s))
496+
elif not self.cmin and s<=self.vmin:
497+
raise RuntimeError('Value must be > %f; found "%f"'%(self.vmin, s))
498+
499+
if self.cmax and s>self.vmax:
500+
raise RuntimeError('Value must be <= %f; found "%f"'%(self.vmax, s))
501+
elif not self.cmax and s>=self.vmax:
502+
raise RuntimeError('Value must be < %f; found "%f"'%(self.vmax, s))
503+
return s
504+
505+
506+
507+
478508
# a map from key -> value, converter
479509
defaultParams = {
480510
'backend' : ['GTK', str],
@@ -574,6 +604,14 @@ def validate_verbose_fileo(s):
574604
'figure.facecolor' : [ 0.75, validate_color], # facecolor; scalar gray
575605
'figure.edgecolor' : [ 'w', validate_color], # edgecolor; white
576606

607+
'figure.subplot.left' : [0.125, ValidateInterval(0, 1, closedmin=False, closedmax=False)],
608+
'figure.subplot.right' : [0.9, ValidateInterval(0, 1, closedmin=False, closedmax=False)],
609+
'figure.subplot.bottom' : [0.1, ValidateInterval(0, F438 1, closedmin=False, closedmax=False)],
610+
'figure.subplot.top' : [0.9, ValidateInterval(0, 1, closedmin=False, closedmax=False)],
611+
'figure.subplot.wspace' : [0.2, ValidateInterval(0, 1, closedmin=False, closedmax=True)],
612+
'figure.subplot.hspace' : [0.2, ValidateInterval(0, 1, closedmin=False, closedmax=True)],
613+
614+
577615
'savefig.dpi' : [ 150, validate_float], # DPI
578616
'savefig.facecolor' : [ 'w', validate_color], # facecolor; white
579617
'savefig.edgecolor' : [ 'w', validate_color], # edgecolor; white

lib/matplotlib/axes.py

Lines changed: 57 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -575,8 +575,9 @@ def axvspan(self, xmin, xmax, ymin=0, ymax=1, **kwargs):
575575
576576
"""
577577

578+
578579
trans = blend_xy_sep_transform( self.transData, self.transAxes )
579-
verts = (xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)
580+
verts = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)]
580581
p = Polygon(verts, **kwargs)
581582
p.set_transform(trans)
582583
self.add_patch(p)
@@ -3652,33 +3653,59 @@ class SubplotBase:
36523653
Subplot(211) # 2 rows, 1 column, first (upper) plot
36533654
"""
36543655

3655-
def __init__(self, *args):
3656-
# Axes __init__ below
3656+
def __init__(self, fig, *args, **kwargs):
3657+
"""
3658+
fig is a figure instance
3659+
3660+
args is a varargs to specify the subplot
3661+
3662+
"""
3663+
3664+
self.figure = fig
36573665

36583666
if len(args)==1:
3659-
s = str(*args)
3667+
s = str(args[0])
36603668
if len(s) != 3:
3661-
raise ValueError, 'Argument to subplot must be a 3 digits long'
3669+
raise ValueError('Argument to subplot must be a 3 digits long')
36623670
rows, cols, num = map(int, s)
36633671
elif len(args)==3:
36643672
rows, cols, num = args
36653673
else:
3666-
raise ValueError, 'Illegal argument to subplot'
3674+
raise ValueError( 'Illegal argument to subplot')
3675+
3676+
36673677
total = rows*cols
36683678
num -= 1 # convert from matlab to python indexing ie num in range(0,total)
36693679
if num >= total:
3670-
raise ValueError, 'Subplot number exceeds total subplots'
3671-
left, right = .125, .9
3672-
bottom, top = .11, .9
3673-
rat = 0.2 # ratio of fig to seperator for multi row/col figs
3680+
raise ValueError( 'Subplot number exceeds total subplots')
3681+
self._rows = rows
3682+
self._cols = cols
3683+
self._num = num
3684+
3685+
self.update_params()
3686+
3687+
def update_params(self):
3688+
'update the subplot position from fig.subplotpars'
3689+
3690+
rows = self._rows
3691+
cols = self._cols
3692+
num = self._num
3693+
3694+
pars = self.figure.subplotpars
3695+
left = pars.left
3696+
right = pars.right
3697+
bottom = pars.bottom
3698+
top = pars.top
3699+
wspace = pars.wspace
3700+
hspace = pars.hspace
36743701
totWidth = right-left
36753702
totHeight = top-bottom
36763703

3677-
figH = totHeight/(rows + rat*(rows-1))
3678-
sepH = rat*figH
3704+
figH = totHeight/(rows + hspace*(rows-1))
3705+
sepH = hspace*figH
36793706

3680-
figW = totWidth/(cols + rat*(cols-1))
3681-
sepW = rat*figW
3707+
figW = totWidth/(cols + wspace*(cols-1))
3708+
sepW = wspace*figW
36823709

36833710
rowNum, colNum = divmod(num, cols)
36843711

@@ -3694,6 +3721,19 @@ def __init__(self, *args):
36943721
self.numRows = rows
36953722
self.numCols = cols
36963723

3724+
if 0:
3725+
print 'rcn', rows, cols, num
3726+
print 'lbrt', left, bottom, right, top
3727+
print 'self.figBottom', self.figBottom
3728+
print 'self.figLeft', self.figLeft
3729+
print 'self.figW', self.figW
3730+
print 'self.figH', self.figH
3731+
print 'self.rowNum', self.rowNum
3732+
print 'self.colNum', self.colNum
3733+
print 'self.numRows', self.numRows
3734+
print 'self.numCols', self.numCols
3735+
3736+
36973737
def is_first_col(self):
36983738
return self.colNum==0
36993739

@@ -3722,7 +3762,7 @@ class Subplot(SubplotBase, Axes):
37223762
Subplot(211) # 2 rows, 1 column, first (upper) plot
37233763
"""
37243764
def __init__(self, fig, *args, **kwargs):
3725-
SubplotBase.__init__(self, *args)
3765+
SubplotBase.__init__(self, fig, *args)
37263766
Axes.__init__(self, fig, [self.figLeft, self.figBottom,
37273767
self.figW, self.figH], **kwargs)
37283768

@@ -3860,7 +3900,7 @@ def table(self, *args, **kwargs):
38603900
raise NotImplementedError('legend not implemented for polar axes')
38613901

38623902
def autoscale_view(self):
3863-
3903+
'set the view limits to include all the data in the axes'
38643904
self.rintd.set_bounds(0, self.get_rmax())
38653905
rmin, rmax = self.rlocator.autoscale()
38663906
self.rintv.set_bounds(rmin, rmax)
@@ -4098,7 +4138,7 @@ class PolarSubplot(SubplotBase, PolarAxes):
40984138
Subplot(211) # 2 rows, 1 column, first (upper) plot
40994139
"""
41004140
def __init__(self, fig, *args, **kwargs):
4101-
SubplotBase.__init__(self, *args)
4141+
SubplotBase.__init__(self, fig, *args)
41024142
PolarAxes.__init__(self, fig, [self.figLeft, self.figBottom, self.figW, self.figH], **kwargs)
41034143

41044144

lib/matplotlib/figure.py

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,53 @@
1515
from mlab import linspace
1616
from ticker import FormatStrFormatter
1717

18+
19+
class SubplotParams:
20+
"""
21+
A class to hold the parameters for a subplot
22+
"""
23+
def __init__(self, left=None, bottom=None, right=None, top=None,
24+
wspace=None, hspace=None):
25+
"""
26+
All dimensions are fraction of the figure width or height.
27+
All values default to their rc params
28+
29+
The following attributes are available:
30+
31+
left : the left side of the subplots of the figure
32+
right : the right side of the subplots of the figure
33+
bottom : the bottom of the subplots of the figure
34+
top : the top of the subplots of the figure
35+
wspace : the amount of width reserved for blank space between subplots
36+
hspace : the amount of height reserved for white space between subplots
37+
"""
38+
self.update(left, bottom, right, top, wspace, hspace)
39+
40+
def update(self,left=None, bottom=None, right=None, top=None,
41+
wspace=None, hspace=None):
42+
"""
43+
Update the current values. If any kwarg is None, default to
44+
the current value, if set, otherwise to rc
45+
"""
46+
47+
self._update_this('left', left)
48+
self._update_this('right', right)
49+
self._update_this('bottom', bottom)
50+
self._update_this('top', top)
51+
self._update_this('wspace', wspace)
52+
self._update_this('hspace', hspace)
53+
54+
55+
def _update_this(self, s, val):
56+
if val is None:
57+
val = getattr(self, s, None)
58+
if val is None:
59+
key = 'figure.subplot.' + s
60+
val = rcParams[key]
61+
62+
setattr(self, s, val)
63+
64+
1865
class Figure(Artist):
1966

2067
def __init__(self,
@@ -24,10 +71,12 @@ def __init__(self,
2471
edgecolor = None, # defaults to rc figure.edgecolor
2572
linewidth = 1.0, # the default linewidth of the frame
2673
frameon = True,
74+
subplotpars = None, # default to rc
2775
):
2876
"""
2977
paper size is a w,h tuple in inches
30-
DPI is dots per inch
78+
DPI is dots per inch
79+
subplotpars is a SubplotParams instance, defaults to rc
3180
"""
3281
Artist.__init__(self)
3382
#self.set_figure(self)
@@ -62,6 +111,12 @@ def __init__(self,
62111

63112
self._hold = rcParams['axes.hold']
64113
self.canvas = None
114+
115+
if subplotpars is None:
116+
subplotpars = SubplotParams()
117+
118+
self.subplotpars = subplotpars
119+
65120
self.clf()
66121

67122
def set_canvas(self, canvas):
@@ -597,6 +652,21 @@ def colorbar(self, mappable, tickfmt='%1.1f', cax=None, orientation='vertical'):
597652
return cax
598653

599654

655+
def subplots_adjust(self, *args, **kwargs):
656+
"""
657+
fig.subplots_adjust(left=None, bottom=None, right=None, wspace=None, hspace=None):
658+
Update the SubplotParams with kwargs (defaulting to rc where
659+
None) and update the subplot locations
660+
"""
661+
self.subplotpars.update(*args, **kwargs)
662+
import matplotlib.axes
663+
for ax in self.axes:
664+
if not isinstance(ax, matplotlib.axes.Subplot): continue
665+
ax.update_params()
666+
ax.set_position([ax.figLeft, ax.figBottom, ax.figW, ax.figH])
667+
668+
669+
600670
def figaspect(arr):
601671
"""
602672
Determine the width and height for a figure that would fit array
@@ -638,3 +708,4 @@ def figaspect(arr):
638708
# the min/max dimensions (we don't want figures 10 feet tall!)
639709
newsize = clip(newsize,figsize_min,figsize_max)
640710
10000 return newsize
711+

lib/matplotlib/lines.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,10 @@ def __init__(self, xdata, ydata,
153153
markersize is the size of the marker in points
154154
markeredgecolor and markerfacecolor can be any color arg
155155
markeredgewidth is the size of the markter edge in points
156-
156+
dash_capstyle set the capstyle for dashed line
157+
solid_capstyle set the capstyle for solid line
158+
dash_joinstyle set the joinstyle for dashed line
159+
solid_joinstyle set the joinstyle for solid line
157160
"""
158161
Artist.__init__(self)
159162

lib/matplotlib/patches.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,11 +350,15 @@ class Polygon(Patch):
350350
"""
351351
def __init__(self, xy, **kwargs):
352352
Patch.__init__(self, **kwargs)
353+
if not isinstance(xy, list):
354+
xy = list(xy)
353355
self.xy = xy
354356

355357
def get_verts(self):
356358
return self.xy
357-
359+
360+
361+
358362

359363
class Wedge(Polygon):
360364
def __init__(self, center, r, theta1, theta2,

0 commit comments

Comments
 (0)
0