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

Skip to content

Commit 9a256a9

Browse files
committed
More aspect-handling cleanups; new axis('image') mode.
svn path=/trunk/matplotlib/; revision=2241
1 parent 0ccf1f7 commit 9a256a9

4 files changed

Lines changed: 85 additions & 58 deletions

File tree

CHANGELOG

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
2006-03-30 Fixed a bug in aspect ratio handling; blocked potential
2+
crashes when panning with button 3; added axis('image')
3+
support. - EF
4+
15
2006-03-28 More changes to aspect ratio handling; new PBox class
26
in new file pbox.py to facilitate resizing and repositioning
37
axes; made PolarAxes maintain unit aspect ratio. - EF

lib/matplotlib/axes.py

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ def set_anchor(self, anchor):
445445

446446
def apply_aspect(self, data_ratio = None):
447447
'''
448-
Use self._aspect and self._aspect_adjusts to modify the
448+
Use self._aspect and self._adjustable to modify the
449449
axes box or the view limits.
450450
'''
451451

@@ -466,18 +466,14 @@ def apply_aspect(self, data_ratio = None):
466466
figW,figH = self.get_figure().get_size_inches()
467467
fig_aspect = figH/figW
468468
xmin,xmax = self.get_xlim()
469-
xsize = math.fabs(xmax-xmin)
469+
xsize = max(math.fabs(xmax-xmin), 1e-30)
470470
ymin,ymax = self.get_ylim()
471-
ysize = math.fabs(ymax-ymin)
471+
ysize = max(math.fabs(ymax-ymin), 1e-30)
472472
if self._adjustable == 'box':
473473
if data_ratio is None:
474474
data_ratio = ysize/xsize
475475
box_aspect = A * data_ratio
476476
pb = PBox(self._originalPosition)
477-
#print xmin, xmax, ymin, ymax
478-
#print pb
479-
#print figH, figW
480-
#print box_aspect, fig_aspect
481477
pb1 = pb.shrink_to_aspect(box_aspect, fig_aspect)
482478
self.set_position(pb1.anchor(self._anchor), 'active')
483479
return
@@ -486,21 +482,26 @@ def apply_aspect(self, data_ratio = None):
486482
(self._sharex or self._masterx))
487483
changey = ((self._sharex or self._masterx) and not
488484
(self._sharey or self._mastery))
489-
xmin,xmax = self.get_xlim()
490-
xsize = math.fabs(xmax-xmin)
491-
ymin,ymax = self.get_ylim()
492-
ysize = math.fabs(ymax-ymin)
493-
l,b,w,h = self._originalPosition
485+
if changex and changey:
486+
warnings.warn("adjustable='datalim' cannot work with shared x and y axes")
487+
return
488+
dx0, dx1 = self.dataLim.intervalx().get_bounds()
489+
dy0, dy1 = self.dataLim.intervaly().get_bounds()
490+
xr = abs(dx1 - dx0)
491+
yr = abs(dy1 - dy0)
492+
l,b,w,h = self.get_position()
494493
box_aspect = fig_aspect * (h/w)
495494
data_ratio = box_aspect / A
496495
Ysize = data_ratio * xsize
497-
if Ysize > ysize or changey:
496+
Xsize = ysize / data_ratio
497+
if changex:
498+
adjust_y = False
499+
else:
500+
adjust_y = changey or ((Ysize > ysize) and (ysize <= yr))
501+
if adjust_y:
498502
dy = 0.5 * (Ysize - ysize)
499503
self.set_ylim((ymin-dy, ymax+dy))
500-
return
501-
502-
Xsize = ysize / data_ratio
503-
if Xsize > xsize or changex:
504+
else:
504505
dx = 0.5 * (Xsize - xsize)
505506
self.set_xlim((xmin-dx, xmax+dx))
506507

lib/matplotlib/backend_bases.py

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"""
55

66
from __future__ import division
7-
import sys
7+
import sys, warnings
88

99
from cbook import is_string_like, enumerate, strip_math, Stack
1010
from colors import colorConverter
@@ -134,7 +134,7 @@ def draw_line_collection(self, segments, transform, clipbox,
134134
color = colors[i % Nc]
135135
rgb = color[0], color[1], color[2]
136136
alpha = color[-1]
137-
137+
138138
gc.set_foreground(rgb, isRGB=True)
139139
gc.set_alpha( alpha )
140140
gc.set_linewidth( linewidths[i % Nlw] )
@@ -1320,30 +1320,45 @@ def format_deltas(event,dx,dy):
13201320
ymin -= dy
13211321
ymax -= dy
13221322
elif self._button_pressed==3:
1323-
dx=(lastx-event.x)/float(a.bbox.width())
1324-
dy=(lasty-event.y)/float(a.bbox.height())
1325-
dx,dy=format_deltas(event,dx,dy)
1326-
alphax = pow(10.0,dx)
1327-
alphay = pow(10.0,dy)#use logscaling, avoid singularities and smother scaling...
1328-
lastx, lasty = trans.inverse_xy_tup( (lastx, lasty) )
1329-
if a.get_xscale()=='log':
1330-
xmin = lastx*(xmin/lastx)**alphax
1331-
xmax = lastx*(xmax/lastx)**alphax
1332-
else:
1333-
xmin = lastx+alphax*(xmin-lastx)
1334-
xmax = lastx+alphax*(xmax-lastx)
1335-
if a.get_yscale()=='log':
1336-
ymin = lasty*(ymin/lasty)**alphay
1337-
ymax = lasty*(ymax/lasty)**alphay
1338-
else:
1339-
ymin = lasty+alphay*(ymin-lasty)
1340-
ymax = lasty+alphay*(ymax-lasty)
1341-
1342-
a.set_xlim((xmin, xmax))
1343-
a.set_ylim((ymin, ymax))
1323+
try:
1324+
dx=(lastx-event.x)/float(a.bbox.width())
1325+
dy=(lasty-event.y)/float(a.bbox.height())
1326+
dx,dy=format_deltas(event,dx,dy)
1327+
alphax = pow(10.0,dx)
1328+
alphay = pow(10.0,dy)#use logscaling, avoid singularities and smother scaling...
1329+
lastx, lasty = trans.inverse_xy_tup( (lastx, lasty) )
1330+
if a.get_xscale()=='log':
1331+
xmin = lastx*(xmin/lastx)**alphax
1332+
xmax = lastx*(xmax/lastx)**alphax
1333+
else:
1334+
xmin = lastx+alphax*(xmin-lastx)
1335+
xmax = lastx+alphax*(xmax-lastx)
1336+
if a.get_yscale()=='log':
1337+
ymin = lasty*(ymin/lasty)**alphay
1338+
ymax = lasty*(ymax/lasty)**alphay
1339+
else:
1340+
ymin = lasty+alphay*(ymin-lasty)
1341+
ymax = lasty+alphay*(ymax-lasty)
1342+
except OverflowError:
1343+
warnings.warn('Overflow while panning')
1344+
return
1345+
a.set_xlim(self.nonsingular(xmin, xmax))
1346+
a.set_ylim(self.nonsingular(ymin, ymax))
13441347

13451348
self.dynamic_update()
13461349

1350+
def nonsingular(self, x0, x1):
1351+
'''Desperate hack to prevent crashes when button-3 panning with
1352+
axis('image') in effect.
1353+
'''
1354+
d = x1 - x0
1355+
# much smaller thresholds seem to cause Value Error
1356+
# later in Transformation::freeze in axes.draw()
1357+
if abs(d) < 1e-10:
1358+
warnings.warn('Axis data limit is too small for panning')
1359+
x1 += 1e-10
1360+
x0 -= 1e-10
1361+
return (x0, x1)
13471362

13481363

13491364
def release_zoom(self, event):

lib/matplotlib/pylab.py

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -575,30 +575,32 @@ def axis(*v, **kwargs):
575575
"""
576576
Set/Get the axis properties::
577577
578-
axis() returns the current axis as a length a length 4 vector
578+
v = axis() returns the current axes as v = [xmin, xmax, ymin, ymax]
579579
580-
axis(v) where v = [xmin, xmax, ymin, ymax] sets the min and max of the x
581-
and y axis limits
580+
axis(v) where v = [xmin, xmax, ymin, ymax] sets the min and max
581+
of the x and y axes
582582
583583
axis('off') turns off the axis lines and labels
584584
585-
axis('equal') changes limits of x or y axis such that equal
586-
tick mark increments are equal in size. This makes a
587-
circle look like a circle, for example. This is persistent.
588-
For example, when axis limits are changed after this command,
589-
the scale remains equal
585+
axis('equal') changes limits of x or y axis so that equal
586+
increments of x and y have the same length; a circle
587+
is circular.
590588
591-
axis('scaled') makes scale equal, changes lengths of axes while
592-
keeping limits of x and y axes fixed. Keeps lower left hand corner
593-
in original position. Fixes axis limits.
589+
axis('scaled') achieves the same result by changing the
590+
dimensions of the plot box instead of the axis data
591+
limits.
594592
595-
axis('tight') changes limits x and y axis such that all data is
593+
axis('tight') changes x and y axis limits such that all data is
596594
shown. If all data is already shown, it will move it to the center
597595
of the figure without modifying (xmax-xmin) or (ymax-ymin). Note
598-
this is slightly different than in matlab. Fixes axis limits.
596+
this is slightly different than in matlab.
599597
600-
axis('normal') or 'auto' sets the axis to normal, i.e.
601-
turns equal scale off
598+
axis('image') is 'scaled' with the axis limits equal to the
599+
data limits.
600+
601+
axis('auto') or 'normal' (deprecated) restores default behavior;
602+
axis limits are automatically scaled to make the data fit
603+
comfortably within the plot box.
602604
603605
if len(*v)==0, you can pass in xmin, xmax, ymin, ymax as kwargs
604606
selectively to alter just those limits w/o changing the others.
@@ -612,18 +614,23 @@ def axis(*v, **kwargs):
612614
s = v[0].lower()
613615
if s=='on': ax.set_axis_on()
614616
elif s=='off': ax.set_axis_off()
615-
elif s in ('equal', 'tight', 'scaled', 'normal', 'auto'):
617+
elif s in ('equal', 'tight', 'scaled', 'normal', 'auto', 'image'):
616618
ax.set_autoscale_on(True)
617619
ax.set_aspect('auto')
618620
ax.autoscale_view()
619621
ax.apply_aspect()
620622
if s=='equal':
621623
ax.set_aspect('equal', adjustable='datalim')
624+
elif s == 'scaled':
625+
ax.set_aspect('equal', adjustable='box', anchor='C')
622626
elif s=='tight':
623627
ax.autoscale_view(tight=True)
624628
ax.set_autoscale_on(False)
625-
elif s=='scaled':
626-
ax.set_aspect('equal', adjustable='box')
629+
elif s == 'image':
630+
ax.autoscale_view(tight=True)
631+
ax.set_autoscale_on(False)
632+
ax.set_aspect('equal', adjustable='box', anchor='C')
633+
627634
else:
628635
raise ValueError('Unrecognized string %s to axis; try on or off' % s)
629636
xmin, xmax = ax.get_xlim()

0 commit comments

Comments
 (0)