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

Skip to content

Commit 42a852d

Browse files
committed
Merge pull request #4310 from insertroar/master
ENH: 'square' argument to `Axes.axis`
2 parents 61591cf + 50af626 commit 42a852d

File tree

4 files changed

+85
-9
lines changed

4 files changed

+85
-9
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Square Plot
2+
-------------------------
3+
4+
Square plot:
5+
6+
Implemented square plots feature as a new parameter in the axis function. When argument 'square' is specified, equal scaling is set, and the limits are set such that xmax-xmin == ymax-ymin.
7+
8+
Example:
9+
10+
``ax.axis('square')``
11+

lib/matplotlib/axes/_base.py

Lines changed: 58 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1301,26 +1301,67 @@ def apply_aspect(self, position=None):
13011301
self.set_xbound((x0, x1))
13021302

13031303
def axis(self, *v, **kwargs):
1304-
"""
1305-
Convenience method for manipulating the x and y view limits
1306-
and the aspect ratio of the plot. For details, see
1307-
:func:`~matplotlib.pyplot.axis`.
1304+
"""Set axis properties.
1305+
1306+
Valid signatures::
1307+
1308+
xmin, xmax, ymin, ymax = axis()
1309+
xmin, xmax, ymin, ymax = axis(list_arg)
1310+
xmin, xmax, ymin, ymax = axis(string_arg)
1311+
xmin, xmax, ymin, ymax = axis(**kwargs)
1312+
1313+
Parameters
1314+
----------
1315+
v : list of float or {'on', 'off', 'equal', 'tight', 'scaled',\
1316+
'normal', 'auto', 'image', 'square'}
1317+
Optional positional argument
1318+
1319+
Axis data limits set from a list; or a command relating to axes:
1320+
1321+
========== ================================================
1322+
Value Description
1323+
========== ================================================
1324+
'on' Toggle axis lines and labels on
1325+
'off' Toggle axis lines and labels off
1326+
'equal' Equal scaling by changing limits
1327+
'scaled' Equal scaling by changing box dimensions
1328+
'tight' Limits set such that all data is shown
1329+
'auto' Automatic scaling, fill rectangle with data
1330+
'normal' Same as 'auto'; deprecated
1331+
'image' 'scaled' with axis limits equal to data limits
1332+
'square' Square plot; similar to 'scaled', but initially\
1333+
forcing xmax-xmin = ymax-ymin
1334+
========== ================================================
1335+
1336+
emit : bool, optional
1337+
Passed to set_{x,y}lim functions, if observers
1338+
are notified of axis limit change
1339+
1340+
xmin, ymin, xmax, ymax : float, optional
1341+
The axis limits to be set
1342+
1343+
Returns
1344+
-------
1345+
xmin, xmax, ymin, ymax : float
1346+
The axis limits
13081347
1309-
*kwargs* are passed on to :meth:`set_xlim` and
1310-
:meth:`set_ylim`
13111348
"""
1349+
13121350
if len(v) == 0 and len(kwargs) == 0:
13131351
xmin, xmax = self.get_xlim()
13141352
ymin, ymax = self.get_ylim()
13151353
return xmin, xmax, ymin, ymax
13161354

1355+
emit = kwargs.get('emit', True)
1356+
13171357
if len(v) == 1 and is_string_like(v[0]):
13181358
s = v[0].lower()
13191359
if s == 'on':
13201360
self.set_axis_on()
13211361
elif s == 'off':
13221362
self.set_axis_off()
1323-
elif s in ('equal', 'tight', 'scaled', 'normal', 'auto', 'image'):
1363+
elif s in ('equal', 'tight', 'scaled', 'normal',
1364+
'auto', 'image', 'square'):
13241365
self.set_autoscale_on(True)
13251366
self.set_aspect('auto')
13261367
self.autoscale_view(tight=False)
@@ -1337,15 +1378,23 @@ def axis(self, *v, **kwargs):
13371378
self.autoscale_view(tight=True)
13381379
self.set_autoscale_on(False)
13391380
self.set_aspect('equal', adjustable='box', anchor='C')
1340-
1381+
elif s == 'square':
1382+
self.set_aspect('equal', adjustable='box', anchor='C')
1383+
self.set_autoscale_on(False)
1384+
xlim = self.get_xlim()
1385+
ylim = self.get_ylim()
1386+
edge_size = max(np.diff(xlim), np.diff(ylim))
1387+
self.set_xlim([xlim[0], xlim[0] + edge_size],
1388+
emit=emit, auto=False)
1389+
self.set_ylim([ylim[0], ylim[0] + edge_size],
1390+
emit=emit, auto=False)
13411391
else:
13421392
raise ValueError('Unrecognized string %s to axis; '
13431393
'try on or off' % s)
13441394
xmin, xmax = self.get_xlim()
13451395
ymin, ymax = self.get_ylim()
13461396
return xmin, xmax, ymin, ymax
13471397

1348-
emit = kwargs.get('emit', True)
13491398
try:
13501399
v[0]
13511400
except IndexError:

lib/matplotlib/pyplot.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,6 +1480,12 @@ def axis(*v, **kwargs):
14801480
as kwargs selectively to alter just those limits without changing
14811481
the others.
14821482
1483+
>>> axis('square')
1484+
1485+
changes the limit ranges (*xmax*-*xmin*) and (*ymax*-*ymin*) of
1486+
the *x* and *y* axes to be the same, and have the same scaling,
1487+
resulting in a square plot.
1488+
14831489
The xmin, xmax, ymin, ymax tuple is returned
14841490
14851491
.. seealso::

lib/matplotlib/tests/test_axes.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3679,6 +3679,16 @@ def test_bar_negative_width():
36793679
assert_equal(b._width, 1)
36803680
assert_equal(b._height, indx + 1)
36813681

3682+
@cleanup
3683+
def test_square_plot():
3684+
x = np.arange(4)
3685+
y = np.array([1., 3., 5., 7.])
3686+
fig, ax = plt.subplots()
3687+
ax.plot(x, y, 'mo')
3688+
ax.axis('square')
3689+
xlim, ylim = ax.get_xlim(), ax.get_ylim()
3690+
assert_true(np.diff(xlim) == np.diff(ylim))
3691+
assert_true(ax.get_aspect() == 'equal')
36823692

36833693
@cleanup
36843694
def test_no_None():

0 commit comments

Comments
 (0)