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

Skip to content

Commit 08c2062

Browse files
committed
Add location keyword argument to Colorbar
1 parent 69cf385 commit 08c2062

File tree

5 files changed

+404
-15
lines changed

5 files changed

+404
-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 on). The
8+
*orientation* and *ticklocation* are no longer required to be provided as they
9+
are 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: 48 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@
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* location value must
47+
match *orientation*. For example, a horizontal colorbar can only have ticks
48+
at the top or the bottom.
49+
4550
fraction : float, default: 0.15
4651
Fraction of original axes to use for colorbar.
4752
@@ -249,13 +254,19 @@ class Colorbar:
249254
alpha : float
250255
The colorbar transparency between 0 (transparent) and 1 (opaque).
251256
252-
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, 'vertical'.
253260
254261
ticklocation : {'auto', 'left', 'right', 'top', 'bottom'}
255262
256263
drawedges : bool
257264
258265
filled : bool
266+
267+
location : None or {'left', 'right', 'top', 'bottom'}
268+
%s
269+
259270
%(_colormap_kw_doc)s
260271
"""
261272

@@ -267,7 +278,7 @@ def __init__(self, ax, mappable=None, *, cmap=None,
267278
alpha=None,
268279
values=None,
269280
boundaries=None,
270-
orientation='vertical',
281+
orientation=None,
271282
ticklocation='auto',
272283
extend=None,
273284
spacing='uniform', # uniform or proportional
@@ -278,6 +289,7 @@ def __init__(self, ax, mappable=None, *, cmap=None,
278289
extendfrac=None,
279290
extendrect=False,
280291
label='',
292+
location=None,
281293
):
282294

283295
if mappable is None:
@@ -308,14 +320,23 @@ def __init__(self, ax, mappable=None, *, cmap=None,
308320
mappable.colorbar_cid = mappable.callbacks.connect(
309321
'changed', self.update_normal)
310322

323+
location_orientation = _get_orientation_from_location(location)
324+
311325
_api.check_in_list(
312-
['vertical', 'horizontal'], orientation=orientation)
326+
[None, 'vertical', 'horizontal'], orientation=orientation)
313327
_api.check_in_list(
314328
['auto', 'left', 'right', 'top', 'bottom'],
315329
ticklocation=ticklocation)
316330
_api.check_in_list(
317331
['uniform', 'proportional'], spacing=spacing)
318332

333+
if location_orientation is not None and orientation is not None:
334+
if location_orientation != orientation:
335+
raise TypeError(
336+
"location and orientation are mutually exclusive")
337+
else:
338+
orientation = orientation or location_orientation or "vertical"
339+
319340
self.ax = ax
320341
self.ax._axes_locator = _ColorbarAxesLocator(self)
321342

@@ -374,7 +395,8 @@ def __init__(self, ax, mappable=None, *, cmap=None,
374395
self.__scale = None # linear, log10 for now. Hopefully more?
375396

376397
if ticklocation == 'auto':
377-
ticklocation = 'bottom' if orientation == 'horizontal' else 'right'
398+
ticklocation = _get_ticklocation_from_orientation(
399+
orientation) if location is None else location
378400
self.ticklocation = ticklocation
379401

380402
self.set_label(label)
@@ -1335,25 +1357,36 @@ def drag_pan(self, button, key, x, y):
13351357

13361358
def _normalize_location_orientation(location, orientation):
13371359
if location is None:
1338-
location = _api.check_getitem(
1339-
{None: "right", "vertical": "right", "horizontal": "bottom"},
1340-
orientation=orientation)
1360+
location = _get_ticklocation_from_orientation(orientation)
13411361
loc_settings = _api.check_getitem({
1342-
"left": {"location": "left", "orientation": "vertical",
1343-
"anchor": (1.0, 0.5), "panchor": (0.0, 0.5), "pad": 0.10},
1344-
"right": {"location": "right", "orientation": "vertical",
1345-
"anchor": (0.0, 0.5), "panchor": (1.0, 0.5), "pad": 0.05},
1346-
"top": {"location": "top", "orientation": "horizontal",
1347-
"anchor": (0.5, 0.0), "panchor": (0.5, 1.0), "pad": 0.05},
1348-
"bottom": {"location": "bottom", "orientation": "horizontal",
1349-
"anchor": (0.5, 1.0), "panchor": (0.5, 0.0), "pad": 0.15},
1362+
"left": {"location": "left", "anchor": (1.0, 0.5),
1363+
"panchor": (0.0, 0.5), "pad": 0.10},
1364+
"right": {"location": "right", "anchor": (0.0, 0.5),
1365+
"panchor": (1.0, 0.5), "pad": 0.05},
1366+
"top": {"location": "top", "anchor": (0.5, 0.0),
1367+
"panchor": (0.5, 1.0), "pad": 0.05},
1368+
"bottom": {"location": "bottom", "anchor": (0.5, 1.0),
1369+
"panchor": (0.5, 0.0), "pad": 0.15},
13501370
}, location=location)
1371+
loc_settings["orientation"] = _get_orientation_from_location(location)
13511372
if orientation is not None and orientation != loc_settings["orientation"]:
13521373
# Allow the user to pass both if they are consistent.
13531374
raise TypeError("location and orientation are mutually exclusive")
13541375
return loc_settings
13551376

13561377

1378+
def _get_orientation_from_location(location):
1379+
return _api.check_getitem(
1380+
{None: None, "left": "vertical", "right": "vertical",
1381+
"top": "horizontal", "bottom": "horizontal"}, location=location)
1382+
1383+
1384+
def _get_ticklocation_from_orientation(orientation):
1385+
return _api.check_getitem(
1386+
{None: "right", "vertical": "right", "horizontal": "bottom"},
1387+
orientation=orientation)
1388+
1389+
13571390
@_docstring.interpd
13581391
def make_axes(parents, location=None, orientation=None, fraction=0.15,
13591392
shrink=1.0, aspect=20, **kwargs):

0 commit comments

Comments
 (0)