New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Square plots #4310
Square plots #4310
Changes from 7 commits
d6848b1
3f6dd49
bb45d27
53a2d2c
ee5ccc7
7b73d0a
c982755
50af626
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
Square Plot | ||
------------------------- | ||
|
||
Square plot: | ||
|
||
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. | ||
|
||
Example: | ||
|
||
``ax.axis('square')`` | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1286,26 +1286,68 @@ def apply_aspect(self, position=None): | |
self.set_xbound((x0, x1)) | ||
|
||
def axis(self, *v, **kwargs): | ||
""" | ||
Convenience method for manipulating the x and y view limits | ||
and the aspect ratio of the plot. For details, see | ||
:func:`~matplotlib.pyplot.axis`. | ||
"""Set axis properties. | ||
|
||
If no positional or kwargs are given, returns the current | ||
axes limits are returned with no side effects. | ||
|
||
If a positional argument is passed the keyword arguments are ignored. | ||
|
||
If no positional argument is passed, the keyword arguments are used. | ||
|
||
Parameters | ||
---------- | ||
v : list of float or {'on', 'off', 'equal', 'tight', 'scaled',\ | ||
'normal', 'auto', 'image', 'square'} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you build the docs does this look ok? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The table looks fine to me size wise. There are a lot of options so it On Sun, Apr 19, 2015 at 5:39 PM basharovV notifications@github.com wrote:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sorry, I was referring to the actual padding in the table. It's not consistent with the other tables, but that's just an aesthetic thing. |
||
Optional positional argument | ||
|
||
Value to set the axis settings to. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Value to..." -> "Axis data limits set from a list; or a command relating to axes." This is all a horrible Matlab legacy, and consequently it's a very poor fit for numpydoc. |
||
If a list it is interpreted as [xmin, xmax, ymin, ymax]. | ||
If a string | ||
|
||
========== =============================================== | ||
Value Description | ||
========== =============================================== | ||
'on' Toggle axis lines and labels on | ||
'off' Toggle axis lines and labels off | ||
'equal' Equal scaling by changing limits | ||
'scaled' Equal scaling by changing box dimensions | ||
'tight' Limits set such that all data is shown | ||
'auto' Automatic scaling, fill rectangle with data | ||
'normal' Same as 'auto'; deprecated | ||
'image' 'scaled' with axis limits equal to data limits | ||
'square' Square plot; both axis have equal limit range | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "axis" -> "axes" (plural) |
||
========== =============================================== | ||
|
||
emit : bool, optional | ||
Passed to set_{x,y}lim functions, if observers | ||
are notified of axis limit change | ||
|
||
xmin, ymin, xmax, ymax : float, optional | ||
The axis limits to be set | ||
|
||
Returns | ||
------- | ||
xmin, xmax, ymin, ymax : float | ||
The axis limits | ||
|
||
*kwargs* are passed on to :meth:`set_xlim` and | ||
:meth:`set_ylim` | ||
""" | ||
|
||
if len(v) == 0 and len(kwargs) == 0: | ||
xmin, xmax = self.get_xlim() | ||
ymin, ymax = self.get_ylim() | ||
return xmin, xmax, ymin, ymax | ||
|
||
emit = kwargs.get('emit', True) | ||
|
||
if len(v) == 1 and is_string_like(v[0]): | ||
s = v[0].lower() | ||
if s == 'on': | ||
self.set_axis_on() | ||
elif s == 'off': | ||
self.set_axis_off() | ||
elif s in ('equal', 'tight', 'scaled', 'normal', 'auto', 'image'): | ||
elif s in ('equal', 'tight', 'scaled', 'normal', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The docstring on this method also needs to be updated. |
||
'auto', 'image', 'square'): | ||
self.set_autoscale_on(True) | ||
self.set_aspect('auto') | ||
self.autoscale_view(tight=False) | ||
|
@@ -1322,15 +1364,23 @@ def axis(self, *v, **kwargs): | |
self.autoscale_view(tight=True) | ||
self.set_autoscale_on(False) | ||
self.set_aspect('equal', adjustable='box', anchor='C') | ||
|
||
elif s == 'square': | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs to be documented as a valid input to |
||
self.set_aspect('equal', adjustable='box', anchor='C') | ||
self.set_autoscale_on(False) | ||
xlim = self.get_xlim() | ||
ylim = self.get_ylim() | ||
edge_size = max(np.diff(xlim), np.diff(ylim)) | ||
self.set_xlim([xlim[0], xlim[0] + edge_size], | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to set up a callback on the zoom signal to enforce this after a user zoom, but that may be a bit too involved (as you would need to keep track of the cid and remove it if a different aspect was set. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ignore this comment. |
||
emit=emit, auto=False) | ||
self.set_ylim([ylim[0], ylim[0] + edge_size], | ||
emit=emit, auto=False) | ||
else: | ||
raise ValueError('Unrecognized string %s to axis; ' | ||
'try on or off' % s) | ||
xmin, xmax = self.get_xlim() | ||
ymin, ymax = self.get_ylim() | ||
return xmin, xmax, ymin, ymax | ||
|
||
emit = kwargs.get('emit', True) | ||
try: | ||
v[0] | ||
except IndexError: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1406,6 +1406,12 @@ def axis(*v, **kwargs): | |
as kwargs selectively to alter just those limits without changing | ||
the others. | ||
|
||
>>> axis('square') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is in the part of pyplot which is auto-generated by boilerplate.py so will be overwritten next time it is run. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have checked, the axis function is above the auto-generated part, so the changes will remain. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, sorry for the noise. |
||
|
||
changes the limit ranges (*xmax*-*xmin*) and (*ymax*-*ymin*) of | ||
the *x* and *y* axes to be the same, and have the same scaling, | ||
resulting in a square plot. | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. isn't axis()'s docstring in pyplot autogenerated There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's outside the autogenerated part, running boilerplate.py doesn't affect it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are two for two in confusing devs on this! Which does raise the question why isn't this part of boilerplate generated On Mon, Apr 20, 2015, 18:40 basharovV notifications@github.com wrote:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The boilerplate generation is applied only to plotting functions. It adds the |
||
The xmin, xmax, ymin, ymax tuple is returned | ||
|
||
.. seealso:: | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3635,6 +3635,16 @@ def test_bar_negative_width(): | |
assert_equal(b._width, 1) | ||
assert_equal(b._height, indx + 1) | ||
|
||
@cleanup | ||
def test_square_plot(): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This can probably be done with out an image test, just check that the aspect is equal and the ranges are the same. |
||
x = np.arange(4) | ||
y = np.array([1., 3., 5., 7.]) | ||
fig, ax = plt.subplots() | ||
ax.plot(x, y, 'mo') | ||
ax.axis('square') | ||
xlim, ylim = ax.get_xlim(), ax.get_ylim() | ||
assert_true(np.diff(xlim) == np.diff(ylim)) | ||
assert_true(ax.get_aspect() == 'equal') | ||
|
||
if __name__ == '__main__': | ||
import nose | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can these three explanations above be replaced or enhanced with 3 signatures? It's easier to understand
than the explanation of it. If something like this can't go in the block above, maybe examples can be included.