8000 Merge pull request #742 from dopplershift/imagegrid-colorbars · matplotlib/matplotlib@a203808 · GitHub
[go: up one dir, main page]

Skip to content

Commit a203808

Browse files
committed
Merge pull request #742 from dopplershift/imagegrid-colorbars
Add support to ImageGrid to only place colorbars at the beginning/end of each row/column.
2 parents 5b499f0 + 4d872bb commit a203808

File tree

2 files changed

+164
-18
lines changed

2 files changed

+164
-18
lines changed
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import matplotlib.pyplot as plt
2+
from mpl_toolkits.axes_grid1 import AxesGrid
3+
4+
def get_demo_image():
5+
import numpy as np
6+
from matplotlib.cbook import get_sample_data
7+
f = get_sample_data("axes_grid/bivariate_normal.npy", asfileobj=False)
8+
z = np.load(f)
9+
# z is a numpy array of 15x15
10+
return z, (-3,4,-4,3)
11+
12+
13+
def demo_bottom_cbar(fig):
14+
"""
15+
A grid of 2x2 images with a colorbar for each column.
16+
"""
17+
grid = AxesGrid(fig, 121, # similar to subplot(132)
18+
nrows_ncols = (2, 2),
19+
axes_pad = 0.10,
20+
share_all=True,
21+
label_mode = "1",
22+
cbar_location = "bottom",
23+
cbar_mode="edge",
24+
cbar_pad = 0.25,
25+
cbar_size = "15%",
26+
direction="column"
27+
)
28+
29+
Z, extent = get_demo_image()
30+
cmaps = [plt.get_cmap("autumn"), plt.get_cmap("summer")]
31+
for i in range(4):
32+
im = grid[i].imshow(Z, extent=extent, interpolation="nearest",
33+
cmap=cmaps[i//2])
34+
if i % 2:
35+
cbar = grid.cbar_axes[i//2].colorbar(im)
36+
37+
for cax in grid.cbar_axes:
38+
cax.toggle_label(True)
39+
cax.axis[cax.orientation].set_label("Bar")
40+
41+
# This affects all axes as share_all = True.
42+
grid.axes_llc.set_xticks([-2, 0, 2])
43+
grid.axes_llc.set_yticks([-2, 0, 2])
44+
45+
46+
def demo_right_cbar(fig):
47+
"""
48+
A grid of 2x2 images. Each row has its own colorbar.
49+
"""
50+
51+
grid = AxesGrid(F, 122, # similar to subplot(122)
52+
nrows_ncols = (2, 2),
53+
axes_pad = 0.10,
54+
label_mode = "1",
55+
share_all = True,
56+
cbar_location="right",
57+
cbar_mode="edge",
58+
cbar_size="7%",
59+
cbar_pad="2%",
60+
)
61+
Z, extent = get_demo_image()
62+
cmaps = [plt.get_cmap("spring"), plt.get_cmap("winter")]
63+
for i in range(4):
64+
im = grid[i].imshow(Z, extent=extent, interpolation="nearest",
65+
cmap=cmaps[i//2])
66+
if i % 2:
67+
grid.cbar_axes[i//2].colorbar(im)
68+
69+
for cax in grid.cbar_axes:
70+
cax.toggle_label(True)
71+
cax.axis[cax.orientation].set_label('Foo')
72+
73+
# This affects all axes because we set share_all = True.
74+
grid.axes_llc.set_xticks([-2, 0, 2])
75+
grid.axes_llc.set_yticks([-2, 0, 2])
76+
77+
78+
79+
if 1:
80+
F = plt.figure(1, (5.5, 2.5))
81+
82+
F.subplots_adjust(left=0.05, right=0.93)
83+
84+
demo_bottom_cbar(F)
85+
demo_right_cbar(F)
86+
87+
plt.draw()
88+
plt.show()
89+

lib/mpl_toolkits/axes_grid1/axes_grid.py

Lines changed: 75 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -494,8 +494,8 @@ def __init__(self, fig,
494494
share_all False [ True | False ]
495495
aspect True [ True | False ]
496496
label_mode "L" [ "L" | "1" | "all" ]
497-
cbar_mode None [ "each" | "single" ]
498-
cbar_location "right" [ "right" | "top" ]
497+
cbar_mode None [ "each" | "single" | "edge" ]
498+
cbar_location "right" [ "left" | "right" | "bottom" | "top" ]
499499
cbar_pad None
500500
cbar_size "5%"
501501
cbar_set_cax True [ True | False ]
@@ -631,42 +631,78 @@ def __init__(self, fig,
631631
def _update_locators(self):
632632

633633
h = []
634+
v = []
634635

635636
h_ax_pos = []
636637
h_cb_pos = []
637-
for ax in self._column_refax:
638-
if h: h.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad))
638+
if self._colorbar_mode == "single" and self._colorbar_location in ('left', 'bottom'):
639+
if self._colorbar_location == "left":
640+
#sz = Size.Fraction(Size.AxesX(self.axes_llc), self._nrows)
641+
sz = Size.Fraction(self._nrows, Size.AxesX(self.axes_llc))
642+
h.append(Size.from_any(self._colorbar_size, sz))
643+
h.append(Size.from_any(self._colorbar_pad, sz))
644+
locator = self._divider.new_locator(nx=0, ny=0, ny1=-1)
645+
elif self._colorbar_location == "bottom":
646+
#sz = Size.Fraction(Size.AxesY(self.axes_llc), self._ncols)
647+
sz = Size.Fraction(self._ncols, Size.AxesY(self.axes_llc))
648+
v.append(Size.from_any(self._colorbar_size, sz))
649+
v.append(Size.from_any(self._colorbar_pad, sz))
650+
locator = self._divider.new_locator(nx=0, nx1=-1, ny=0)
651+
for i in range(self.ngrids):
652+
self.cbar_axes[i].set_visible(False)
653+
self.cbar_axes[0].set_axes_locator(locator)
654+
self.cbar_axes[0].set_visible(True)
639655

640-
h_ax_pos.append(len(h))
656+
for col,ax in enumerate(self._column_refax):
657+
if h: h.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad))
641658

642659
if ax:
643660
sz = Size.AxesX(ax)
644661
else:
645662
sz = Size.AxesX(self.axes_llc)
663+
664+
if (self._colorbar_mode == "each" or
665+
(self._colorbar_mode == 'edge' and
666+
col == 0)) and self._colorbar_location == "left":
667+
h_cb_pos.append(len(h))
668+
h.append(Size.from_any(self._colorbar_size, sz))
669+
h.append(Size.from_any(self._colorbar_pad, sz))
670+
671+
h_ax_pos.append(len(h))
672+
646673
h.append(sz)
647674

648-
if self._colorbar_mode == "each" and self._colorbar_location == "right":
675+
if (self._colorbar_mode == "each" or
676+
(self._colorbar_mode == 'edge' and
677+
col == self._ncols - 1)) and self._colorbar_location == "right":
649678
h.append(Size.from_any(self._colorbar_pad, sz))
650679
h_cb_pos.append(len(h))
651680
h.append(Size.from_any(self._colorbar_size, sz))
652681

653682

654-
v = []
655-
656683
v_ax_pos = []
657684
v_cb_pos = []
658-
for ax in self._row_refax[::-1]:
685+
for row,ax in enumerate(self._row_refax[::-1]):
659686
if v: v.append(self._horiz_pad_size) #Size.Fixed(self._axes_pad))
660687

661-
v_ax_pos.append(len(v))
662688
if ax:
663689
sz = Size.AxesY(ax)
664690
else:
665691
sz = Size.AxesY(self.axes_llc)
666-
v.append(sz)
667692

693+
if (self._colorbar_mode == "each" or
694+
(self._colorbar_mode == 'edge' and
695+
row == 0)) and self._colorbar_location == "bottom":
696+
v_cb_pos.append(len(v))
697+
v.append(Size.from_any(self._colorbar_size, sz))
698+
v.append(Size.from_any(self._colorbar_pad, sz))
668699

669-
if self._colorbar_mode == "each" and self._colorbar_location == "top":
700+
v_ax_pos.append(len(v))
701+
v.append(sz)
702+
703+
if (self._colorbar_mode == "each" or
704+
(self._colorbar_mode == 'edge' and
705+
row == self._nrows - 1)) and self._colorbar_location == "top":
670706
v.append(Size.from_any(self._colorbar_pad, sz))
671707
v_cb_pos.append(len(v))
672708
v.append(Size.from_any(self._colorbar_size, sz))
@@ -680,13 +716,24 @@ def _update_locators(self):
680716
self.axes_all[i].set_axes_locator(locator)
681717

682718
if self._colorbar_mode == "each":
683-
if self._colorbar_location == "right":
719+
if self._colorbar_location in ("right", "left"):
684720
locator = self._divider.new_locator(nx=h_cb_pos[col],
685721
ny=v_ax_pos[self._nrows -1 - row])
686-
elif self._colorbar_location == "top":
722+
elif self._colorbar_location in ("top", "bottom"):
687723
locator = self._divider.new_locator(nx=h_ax_pos[col],
688724
ny=v_cb_pos[self._nrows -1 - row])
689725
self.cbar_axes[i].set_axes_locator(locator)
726+
elif self._colorbar_mode == 'edge':
727+
if ((self._colorbar_location == 'left' and col == 0) or
728+
(self._colorbar_location == 'right' and col == self._ncols-1)):
729+
locator = self._divider.new_locator(nx=h_cb_pos[0],
730+
ny=v_ax_pos[self._nrows -1 - row])
731+
self.cbar_axes[row].set_axes_locator(locator)
732+
elif ((self._colorbar_location == 'bottom' and row == self._nrows - 1) or
733+
(self._colorbar_location == 'top' and row == 0)):
734+
locator = self._divider.new_locator(nx=h_ax_pos[col],
735+
ny=v_cb_pos[0])
736+
self.cbar_axes[col].set_axes_locator(locator)
690737

691738

692739
if self._colorbar_mode == "single":
@@ -702,13 +749,23 @@ def _update_locators(self):
702749
v.append(Size.from_any(self._colorbar_pad, sz))
703750
v.append(Size.from_any(self._colorbar_size, sz))
704751
locator = self._divider.new_locator(nx=0, nx1=-1, ny=-2)
705-
for i in range(self.ngrids):
706-
self.cbar_axes[i].set_visible(False)
707-
self.cbar_axes[0].set_axes_locator(locator)
708-
self.cbar_axes[0].set_visible(True)
752+
if self._colorbar_location in ("right", "top"):
753+
for i in ran A165 ge(self.ngrids):
754+
self.cbar_axes[i].set_visible(False)
755+
self.cbar_axes[0].set_axes_locator(locator)
756+
self.cbar_axes[0].set_visible(True)
709757
elif self._colorbar_mode == "each":
710758
for i in range(self.ngrids):
711759
self.cbar_axes[i].set_visible(True)
760+
elif self._colorbar_mode == "edge":
761+
if self._colorbar_location in ('right', 'left'):
762+
count = self._nrows
763+
else:
764+
count = self._ncols
765+
for i in range(count):
766+
self.cbar_axes[i].set_visible(True)
767+
for j in range(i + 1, self.ngrids):
768+
self.cbar_axes[j].set_visible(False)
712769
else:
713770
for i in range(self.ngrids):
714771
self.cbar_axes[i].set_visible(False)

0 commit comments

Comments
 (0)
0