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

Appearance settings

Commit 08c2062

Browse filesBrowse files
committed
Add location keyword argument to Colorbar
1 parent 69cf385 commit 08c2062
Copy full SHA for 08c2062

File tree

Expand file treeCollapse file tree

5 files changed

+404
-15
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+404
-15
lines changed
+25Lines 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

Copy file name to clipboardExpand all lines: lib/matplotlib/colorbar.py
+48-15Lines 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):
Loading

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.