Skip to content

Commit 164a811

Browse files
Add axes3d.automargin rcparam to retain original margin behavior
1 parent eb13ba8 commit 164a811

File tree

7 files changed

+81
-29
lines changed

7 files changed

+81
-29
lines changed

lib/matplotlib/mpl-data/matplotlibrc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,9 @@
424424
#axes.autolimit_mode: data # If "data", use axes.xmargin and axes.ymargin as is.
425425
# If "round_numbers", after application of margins, axis
426426
# limits are further expanded to the nearest "round" number.
427-
#polaraxes.grid: True # display grid on polar axes
428-
#axes3d.grid: True # display grid on 3D axes
427+
#polaraxes.grid: True # display grid on polar axes
428+
#axes3d.grid: True # display grid on 3D axes
429+
#axes3d.automargin: False # automatically add margin when setting 3D axis limits
429430

430431
#axes3d.xaxis.panecolor: (0.95, 0.95, 0.95, 0.5) # background pane on 3D axes
431432
#axes3d.yaxis.panecolor: (0.90, 0.90, 0.90, 0.5) # background pane on 3D axes

lib/matplotlib/mpl-data/stylelib/classic.mplstyle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ axes.spines.left : True
223223
axes.spines.right : True
224224
axes.spines.top : True
225225
polaraxes.grid : True # display grid on polar axes
226-
axes3d.grid : True # display grid on 3d axes
226+
axes3d.grid : True # display grid on 3D axes
227+
axes3d.automargin : False # automatically add margin when setting 3D axis limits
227228

228229
date.autoformatter.year : %Y
229230
date.autoformatter.month : %b %Y

lib/matplotlib/rcsetup.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,8 +1015,10 @@ def _convert_validator_spec(key, conv):
10151015
"axes.ymargin": _range_validators["0 <= x <= 1"], # margin added to yaxis
10161016
'axes.zmargin': _range_validators["0 <= x <= 1"], # margin added to zaxis
10171017

1018-
"polaraxes.grid": validate_bool, # display polar grid or not
1019-
"axes3d.grid": validate_bool, # display 3d grid
1018+
"polaraxes.grid": validate_bool, # display polar grid or not
1019+
"axes3d.grid": validate_bool, # display 3d grid
1020+
"axes3d.automargin": validate_bool, # automatically add margin when
1021+
# setting 3D axis limits
10201022

10211023
"axes3d.xaxis.panecolor": validate_color, # 3d background pane
10221024
"axes3d.yaxis.panecolor": validate_color, # 3d background pane

lib/matplotlib/ticker.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2099,6 +2099,8 @@ def _raw_ticks(self, vmin, vmax):
20992099
steps = steps[igood]
21002100

21012101
raw_step = ((_vmax - _vmin) / nbins)
2102+
if self.axis.axes.name == '3d':
2103+
raw_step = raw_step * 24/25 # needed to match mpl3.7 appearance
21022104
large_steps = steps >= raw_step
21032105
if mpl.rcParams['axes.autolimit_mode'] == 'round_numbers':
21042106
# Classic round_numbers mode may require a larger step.

lib/mpl_toolkits/mplot3d/axes3d.py

Lines changed: 66 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,8 @@ def __init__(
159159
self.M = None
160160

161161
# Initialize margins, which calls autoscale_view
162-
margin = 1/48 # default value
163-
self.margins(x=margin, y=margin, z=margin)
162+
self.margin = 1/48 # default value
163+
self.margins(x=self.margin, y=self.margin, z=self.margin)
164164

165165
# func used to format z -- fall back on major formatters
166166
self.fmt_zdata = None
@@ -349,7 +349,8 @@ def set_aspect(self, aspect, adjustable=None, anchor=None, share=False):
349349
self.set_ylim3d,
350350
self.set_zlim3d)):
351351
if i in ax_indices:
352-
set_lim(mean[i] - deltas[i]/2., mean[i] + deltas[i]/2.)
352+
set_lim(mean[i] - deltas[i]/2., mean[i] + deltas[i]/2.,
353+
auto=None)
353354
else: # 'box'
354355
# Change the box aspect such that the ratio of the length of
355356
# the unmodified axis to the length of the diagonal
@@ -417,8 +418,8 @@ def set_box_aspect(self, aspect, *, zoom=1):
417418
else:
418419
aspect = np.asarray(aspect, dtype=float)
419420
_api.check_shape((3,), aspect=aspect)
420-
# default scale tuned to match the mpl32 appearance.
421-
aspect *= 1.8294640721620434 * zoom / np.linalg.norm(aspect)
421+
# default scale tuned to match the mpl3.2 appearance.
422+
aspect *= 1.905691741835462 * zoom / np.linalg.norm(aspect)
422423

423424
self._box_aspect = aspect
424425
self.stale = True
@@ -692,29 +693,73 @@ def get_w_lims(self):
692693
minz, maxz = self.get_zlim3d()
693694
return minx, maxx, miny, maxy, minz, maxz
694695

695-
# set_xlim, set_ylim are directly inherited from base Axes.
696+
def _set_lim3d(self, axis, lower=None, upper=None, emit=True, auto=False,
697+
margin=None, *, axmin=None, axmax=None):
698+
"""
699+
Set 3D axis limits.
700+
701+
See `.Axes.set_ylim` for full documentation
702+
"""
703+
if upper is None:
704+
if np.iterable(lower):
705+
lower, upper = lower
706+
else:
707+
raise ValueError("Must provide an upper bound.")
708+
if lower is None:
709+
raise ValueError("Must provide a lower bound.")
710+
if axmin is not None:
711+
if lower is not None:
712+
raise TypeError("Cannot pass both 'lower' and 'min'")
713+
lower = axmin
714+
if axmax is not None:
715+
if upper is not None:
716+
raise TypeError("Cannot pass both 'upper' and 'max'")
717+
upper = axmax
718+
if margin is None:
719+
if mpl.rcParams['axes3d.automargin']:
720+
margin = self.margin
721+
else:
722+
margin = 0
723+
delta = (upper - lower) * margin
724+
lower = lower - delta
725+
upper = upper + delta
726+
return axis._set_lim(lower, upper, emit=emit, auto=auto)
727+
728+
@_api.make_keyword_only("3.8", "emit")
729+
def set_xlim(self, left=None, right=None, emit=True, auto=False,
730+
margin=None, *, xmin=None, xmax=None):
731+
"""
732+
Set 3D x limits.
733+
734+
See `.Axes.set_xlim` for full documentation
735+
"""
736+
return self._set_lim3d(self.xaxis, left, right, emit=emit, auto=auto,
737+
margin=margin, axmin=xmin, axmax=xmax)
738+
739+
@_api.make_keyword_only("3.8", "emit")
740+
def set_ylim(self, bottom=None, top=None, emit=True, auto=False,
741+
margin=None, *, ymin=None, ymax=None):
742+
"""
743+
Set 3D y limits.
744+
745+
See `.Axes.set_ylim` for full documentation
746+
"""
747+
return self._set_lim3d(self.yaxis, bottom, top, emit=emit, auto=auto,
748+
margin=margin, axmin=ymin, axmax=ymax)
749+
696750
@_api.make_keyword_only("3.6", "emit")
697751
def set_zlim(self, bottom=None, top=None, emit=True, auto=False,
698-
*, zmin=None, zmax=None):
752+
margin=None, *, zmin=None, zmax=None):
699753
"""
700754
Set 3D z limits.
701755
702756
See `.Axes.set_ylim` for full documentation
703757
"""
704-
if top is None and np.iterable(bottom):
705-
bottom, top = bottom
706-
if zmin is not None:
707-
if bottom is not None:
708-
raise TypeError("Cannot pass both 'bottom' and 'zmin'")
709-
bottom = zmin
710-
if zmax is not None:
711-
if top is not None:
712-
raise TypeError("Cannot pass both 'top' and 'zmax'")
713-
top = zmax
714-
return self.zaxis._set_lim(bottom, top, emit=emit, auto=auto)
715-
716-
set_xlim3d = maxes.Axes.set_xlim
717-
set_ylim3d = maxes.Axes.set_ylim
758+
return self._set_lim3d(self.zaxis, bottom, top, emit=emit, auto=auto,
759+
margin=margin, axmin=zmin, axmax=zmax)
760+
761+
set_xlim3d = set_xlim
762+
set_ylim3d = set_ylim
718763
set_zlim3d = set_zlim
719764

720765
def get_xlim(self):

lib/mpl_toolkits/mplot3d/axis3d.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,7 @@ def draw(self, renderer):
349349

350350
mins, maxs, tc, highs = self._get_coord_info()
351351
centers = 0.5 * (maxs + mins)
352-
deltas = (maxs - mins) / 12 # label offsets
352+
deltas = (maxs - mins) * 1/12 * 23/24 # keep mpl3.7 appearance
353353

354354
minmax = np.where(highs, maxs, mins)
355355
maxmin = np.where(~highs, maxs, mins)
@@ -504,7 +504,6 @@ def draw_grid(self, renderer):
504504
if not self.axes._draw_grid:
505505
return
506506

507-
self.label._transform = self.axes.transData
508507
renderer.open_group("grid3d", gid=self.get_gid())
509508

510509
ticks = self._update_ticks()

lib/mpl_toolkits/mplot3d/tests/test_axes3d.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,7 @@ def test_add_collection3d_zs_array():
927927

928928
assert line is not None
929929

930+
plt.rcParams['axes3d.automargin'] = True
930931
ax.set_xlim(-5, 5)
931932
ax.set_ylim(-4, 6)
932933
ax.set_zlim(-2, 2)
@@ -953,6 +954,7 @@ def test_add_collection3d_zs_scalar():
953954

954955
assert line is not None
955956

957+
plt.rcParams['axes3d.automargin'] = True
956958
ax.set_xlim(-5, 5)
957959
ax.set_ylim(-4, 6)
958960
ax.set_zlim(0, 2)
@@ -977,7 +979,7 @@ def test_axes3d_labelpad():
977979

978980
# Tick labels also respect tick.pad (also from rcParams)
979981
for i, tick in enumerate(ax.yaxis.get_major_ticks()):
980-
tick.set_pad(tick.get_pad() - i * 5)
982+
tick.set_pad(tick.get_pad() + 5 - i * 5)
981983

982984

983985
@mpl3d_image_comparison(['axes3d_cla.png'], remove_text=False)

0 commit comments

Comments
 (0)