Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite87cd5e

Browse files
committed
Add location keyword argument to Colorbar
1 parent98b1f82 commite87cd5e

File tree

3 files changed

+119
-15
lines changed

3 files changed

+119
-15
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
``colorbar`` now has a *location* keyword argument
2+
==================================================
3+
4+
The ``colorbar`` method now supports a *location* keyword argument to more
5+
easily position the color bar. This is useful when providing your own inset
6+
axes using the *cax* keyword argument and behaves similar to the case where
7+
axes are not provided (where the *location* keyword is passed through).
8+
*orientation* and *ticklocation* are no longer required as they are
9+
determined by *location*. *ticklocation* can still be provided if the
10+
automatic setting is not preferred. (*orientation* can also be provided but
11+
must be compatible with the *location*.)
12+
13+
An example is:
14+
15+
..plot::
16+
:include-source: true
17+
18+
import matplotlib.pyplot as plt
19+
import numpy as np
20+
rng = np.random.default_rng(19680801)
21+
imdata = rng.random((10, 10))
22+
fig, ax = plt.subplots()
23+
im = ax.imshow(imdata)
24+
fig.colorbar(im, cax=ax.inset_axes([0, 1.05, 1, 0.05]),
25+
location='top')

‎lib/matplotlib/colorbar.py

Lines changed: 63 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@
4242
of the colorbar, as that also determines the *orientation*; passing
4343
incompatible values for *location* and *orientation* raises an exception.
4444
45+
ticklocation : {'auto', 'left', 'right', 'top', 'bottom'}
46+
The location of the colorbar ticks. The *ticklocation* must match
47+
*orientation*. For example, a horizontal colorbar can only have ticks at
48+
the top or the bottom. If 'auto', the ticks will be the same as *location*,
49+
so a colorbar to the left will have ticks to the left. If *location* is
50+
None, the ticks will be at the bottom for horizontal colorbar and at the
51+
right for a vertical.
52+
4553
fraction : float, default: 0.15
4654
Fraction of original axes to use for colorbar.
4755
@@ -246,13 +254,31 @@ class Colorbar:
246254
alpha : float
247255
The colorbar transparency between 0 (transparent) and 1 (opaque).
248256
249-
orientation : {'vertical', 'horizontal'}
257+
orientation : None or {'vertical', 'horizontal'}
258+
If None, use the value determined by *location*. If both
259+
*orientation* and *location* are None then defaults to 'vertical'.
250260
251261
ticklocation : {'auto', 'left', 'right', 'top', 'bottom'}
262+
The location of the colorbar ticks. The *ticklocation* must match
263+
*orientation*. For example, a horizontal colorbar can only have ticks
264+
at the top or the bottom. If 'auto', the ticks will be the same as
265+
*location*, so a colorbar to the left will have ticks to the left. If
266+
*location* is None, the ticks will be at the bottom for horizontal
267+
colorbar and at the right for a vertical.
252268
253269
drawedges : bool
270+
Whether to draw lines at color boundaries.
254271
255272
filled : bool
273+
274+
location : None or {'left', 'right', 'top', 'bottom'}
275+
The location, relative to the parent axes, where the colorbar axes
276+
is created. It also determines the *orientation* of the colorbar
277+
(colorbars on the left and right are vertical, colorbars at the top
278+
and bottom are horizontal). If None, the location will come from the
279+
*orientation* if it is set (vertical colorbars on the right, horizontal
280+
ones at the bottom), or default to 'right' if *orientation* is unset.
281+
256282
%(_colormap_kw_doc)s
257283
"""
258284

@@ -264,7 +290,7 @@ def __init__(self, ax, mappable=None, *, cmap=None,
264290
alpha=None,
265291
values=None,
266292
boundaries=None,
267-
orientation='vertical',
293+
orientation=None,
268294
ticklocation='auto',
269295
extend=None,
270296
spacing='uniform',# uniform or proportional
@@ -275,6 +301,7 @@ def __init__(self, ax, mappable=None, *, cmap=None,
275301
extendfrac=None,
276302
extendrect=False,
277303
label='',
304+
location=None,
278305
):
279306

280307
ifmappableisNone:
@@ -305,14 +332,23 @@ def __init__(self, ax, mappable=None, *, cmap=None,
305332
mappable.colorbar_cid=mappable.callbacks.connect(
306333
'changed',self.update_normal)
307334

335+
location_orientation=_get_orientation_from_location(location)
336+
308337
_api.check_in_list(
309-
['vertical','horizontal'],orientation=orientation)
338+
[None,'vertical','horizontal'],orientation=orientation)
310339
_api.check_in_list(
311340
['auto','left','right','top','bottom'],
312341
ticklocation=ticklocation)
313342
_api.check_in_list(
314343
['uniform','proportional'],spacing=spacing)
315344

345+
iflocation_orientationisnotNoneandorientationisnotNone:
346+
iflocation_orientation!=orientation:
347+
raiseTypeError(
348+
"location and orientation are mutually exclusive")
349+
else:
350+
orientation=orientationorlocation_orientationor"vertical"
351+
316352
self.ax=ax
317353
self.ax._axes_locator=_ColorbarAxesLocator(self)
318354

@@ -365,7 +401,8 @@ def __init__(self, ax, mappable=None, *, cmap=None,
365401
self.__scale=None# linear, log10 for now. Hopefully more?
366402

367403
ifticklocation=='auto':
368-
ticklocation='bottom'iforientation=='horizontal'else'right'
404+
ticklocation=_get_ticklocation_from_orientation(
405+
orientation)iflocationisNoneelselocation
369406
self.ticklocation=ticklocation
370407

371408
self.set_label(label)
@@ -1330,25 +1367,36 @@ def drag_pan(self, button, key, x, y):
13301367

13311368
def_normalize_location_orientation(location,orientation):
13321369
iflocationisNone:
1333-
location=_api.check_getitem(
1334-
{None:"right","vertical":"right","horizontal":"bottom"},
1335-
orientation=orientation)
1370+
location=_get_ticklocation_from_orientation(orientation)
13361371
loc_settings=_api.check_getitem({
1337-
"left": {"location":"left","orientation":"vertical",
1338-
"anchor": (1.0,0.5),"panchor": (0.0,0.5),"pad":0.10},
1339-
"right": {"location":"right","orientation":"vertical",
1340-
"anchor": (0.0,0.5),"panchor": (1.0,0.5),"pad":0.05},
1341-
"top": {"location":"top","orientation":"horizontal",
1342-
"anchor": (0.5,0.0),"panchor": (0.5,1.0),"pad":0.05},
1343-
"bottom": {"location":"bottom","orientation":"horizontal",
1344-
"anchor": (0.5,1.0),"panchor": (0.5,0.0),"pad":0.15},
1372+
"left": {"location":"left","anchor":(1.0,0.5),
1373+
"panchor": (0.0,0.5),"pad":0.10},
1374+
"right": {"location":"right","anchor":(0.0,0.5),
1375+
"panchor": (1.0,0.5),"pad":0.05},
1376+
"top": {"location":"top","anchor":(0.5,0.0),
1377+
"panchor": (0.5,1.0),"pad":0.05},
1378+
"bottom": {"location":"bottom","anchor":(0.5,1.0),
1379+
"panchor": (0.5,0.0),"pad":0.15},
13451380
},location=location)
1381+
loc_settings["orientation"]=_get_orientation_from_location(location)
13461382
iforientationisnotNoneandorientation!=loc_settings["orientation"]:
13471383
# Allow the user to pass both if they are consistent.
13481384
raiseTypeError("location and orientation are mutually exclusive")
13491385
returnloc_settings
13501386

13511387

1388+
def_get_orientation_from_location(location):
1389+
return_api.check_getitem(
1390+
{None:None,"left":"vertical","right":"vertical",
1391+
"top":"horizontal","bottom":"horizontal"},location=location)
1392+
1393+
1394+
def_get_ticklocation_from_orientation(orientation):
1395+
return_api.check_getitem(
1396+
{None:"right","vertical":"right","horizontal":"bottom"},
1397+
orientation=orientation)
1398+
1399+
13521400
@_docstring.interpd
13531401
defmake_axes(parents,location=None,orientation=None,fraction=0.15,
13541402
shrink=1.0,aspect=20,**kwargs):

‎lib/matplotlib/tests/test_colorbar.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,3 +1149,34 @@ def test_title_text_loc():
11491149
# colorbar axes, including its extend triangles....
11501150
assert (cb.ax.title.get_window_extent(fig.canvas.get_renderer()).ymax>
11511151
cb.ax.spines['outline'].get_window_extent().ymax)
1152+
1153+
1154+
@check_figures_equal(extensions=["png"])
1155+
deftest_passing_location(fig_ref,fig_test):
1156+
ax_ref=fig_ref.add_subplot()
1157+
im=ax_ref.imshow([[0,1], [2,3]])
1158+
ax_ref.figure.colorbar(im,cax=ax_ref.inset_axes([0,1.05,1,0.05]),
1159+
orientation="horizontal",ticklocation="top")
1160+
ax_test=fig_test.add_subplot()
1161+
im=ax_test.imshow([[0,1], [2,3]])
1162+
ax_test.figure.colorbar(im,cax=ax_test.inset_axes([0,1.05,1,0.05]),
1163+
location="top")
1164+
1165+
1166+
@pytest.mark.parametrize("kwargs,error,message", [
1167+
({'location':'top','orientation':'vertical'},TypeError,
1168+
"location and orientation are mutually exclusive"),
1169+
({'location':'top','orientation':'vertical','cax':True},TypeError,
1170+
"location and orientation are mutually exclusive"),# Different to above
1171+
({'ticklocation':'top','orientation':'vertical','cax':True},
1172+
ValueError,"'top' is not a valid value for position"),
1173+
({'location':'top','extendfrac': (0,None)},ValueError,
1174+
"invalid value for extendfrac"),
1175+
])
1176+
deftest_colorbar_errors(kwargs,error,message):
1177+
fig,ax=plt.subplots()
1178+
im=ax.imshow([[0,1], [2,3]])
1179+
ifkwargs.get('cax',None)isTrue:
1180+
kwargs['cax']=ax.inset_axes([0,1.05,1,0.05])
1181+
withpytest.raises(error,match=message):
1182+
fig.colorbar(im,**kwargs)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp