93
94
If mappable is a ContourSet, its extend kwarg is included automatically.
96
Note that the shrink kwarg provides a simple way to keep
97
a vertical colorbar, for example, from being taller than
98
the axes of the mappable to which the colorbar is attached;
99
but it is a manual method requiring some trial and error.
100
If the colorbar is too tall (or a horizontal colorbar is
101
too wide) use a smaller value of shrink.
103
For more precise control, you can manually specify the
104
positions of the axes objects in which the mappable and
105
the colorbar are drawn. In this case, do not use any of the
106
axes properties kwargs.
95
107
''' % (make_axes_kw_doc, colormap_kw_doc)
131
145
self.solids = None
132
146
self.lines = None
133
147
if iterable(ticks):
134
self.locator = ticker.FixedLocator(ticks, nbins=10)
148
self.locator = ticker.FixedLocator(ticks, nbins=len(ticks))
136
150
self.locator = ticks # Handle default in _ticker()
137
151
if format is None:
138
self.formatter = ticker.ScalarFormatter()
152
if isinstance(self.norm, colors.LogNorm):
153
self.formatter = ticker.LogFormatter()
155
self.formatter = ticker.ScalarFormatter()
139
156
elif is_string_like(format):
140
157
self.formatter = ticker.FormatStrFormatter(format)
226
243
def _add_solids(self, X, Y, C):
228
Draw the colors using pcolormesh; optionally add separators.
245
Draw the colors using pcolor; optionally add separators.
247
## Change to pcolormesh if/when it is fixed to handle alpha
230
249
if self.orientation == 'vertical':
233
252
args = (nx.transpose(Y), nx.transpose(X), nx.transpose(C))
234
kw = {'cmap':self.cmap, 'norm':self.norm, 'shading':'flat'}
253
kw = {'cmap':self.cmap, 'norm':self.norm,
254
'shading':'flat', 'alpha':self.alpha}
235
255
col = self.ax.pcolor(*args, **kw)
236
self.add_observer(col)
256
#self.add_observer(col) # We should observe, not be observed...
237
257
self.solids = col
238
258
if self.drawedges:
239
259
self.dividers = LineCollection(self._edges(X,Y),
269
291
formatter = self.formatter
270
292
if locator is None:
271
293
if self.boundaries is None:
272
if isinstance(self.norm, colors.no_norm):
294
if isinstance(self.norm, colors.NoNorm):
273
295
nv = len(self._values)
274
296
base = 1 + int(nv/10)
275
297
locator = ticker.IndexLocator(base=base, offset=0)
298
elif isinstance(self.norm, colors.LogNorm):
299
locator = ticker.LogLocator()
277
301
locator = ticker.MaxNLocator()
279
303
b = self._boundaries[self._inside]
280
304
locator = ticker.FixedLocator(b, nbins=10)
281
if isinstance(self.norm, colors.no_norm):
305
if isinstance(self.norm, colors.NoNorm):
282
306
intv = Interval(Value(self._values[0]), Value(self._values[-1]))
284
308
intv = Interval(Value(self.vmin), Value(self.vmax))
420
441
def _locate(self, x):
422
Return the colorbar data coordinate(s) corresponding to the color
423
value(s) in scalar or array x.
424
Used for tick positioning.
443
Given a possible set of color data values, return the ones
444
within range, together with their corresponding colorbar
447
if isinstance(self.norm, colors.NoNorm):
452
# Do calculations using normalized coordinates so
453
# as to make the interpolation more accurate.
454
b = self.norm(self._boundaries, clip=False).filled()
455
# We do our own clipping so that we can allow a tiny
456
# bit of slop in the end point ticks to allow for
457
# floating point errors.
458
xn = self.norm(x, clip=False).filled()
459
in_cond = (xn > -0.001) & (xn < 1.001)
460
xn = nx.compress(in_cond, xn)
461
xout = nx.compress(in_cond, x)
462
# The rest is linear interpolation with clipping.
429
ii = nx.minimum(nx.searchsorted(b, x), N-1)
465
ii = nx.minimum(nx.searchsorted(b, xn), N-1)
434
466
i0 = nx.maximum(ii - 1, 0)
467
#db = b[ii] - b[i0] (does not work with Numeric)
436
468
db = nx.take(b, ii) - nx.take(b, i0)
437
469
db = nx.where(i0==ii, 1.0, db)
438
470
#dy = y[ii] - y[i0]
439
471
dy = nx.take(y, ii) - nx.take(y, i0)
440
z = nx.take(y, i0) + (x-nx.take(b,i0))*dy/db
472
z = nx.take(y, i0) + (xn-nx.take(b,i0))*dy/db
475
def set_alpha(self, alpha):
445
478
class Colorbar(ColorbarBase):
446
479
def __init__(self, ax, mappable, **kw):
447
mappable.autoscale() # Ensure mappable.norm.vmin, vmax
480
mappable.autoscale_None() # Ensure mappable.norm.vmin, vmax
448
481
# are set when colorbar is called,
449
482
# even if mappable.draw has not yet
450
483
# been called. This will not change
451
484
# vmin, vmax if they are already set.
452
485
self.mappable = mappable
486
kw['cmap'] = mappable.cmap
487
kw['norm'] = mappable.norm
488
kw['alpha'] = mappable.get_alpha()
453
489
if isinstance(mappable, ContourSet):
457
491
kw['boundaries'] = CS._levels
458
492
kw['values'] = CS.cvalues
459
493
kw['extend'] = CS.extend
460
494
#kw['ticks'] = CS._levels
461
kw.setdefault('ticks', CS.levels)
495
kw.setdefault('ticks', ticker.FixedLocator(CS.levels, nbins=10))
462
496
kw['filled'] = CS.filled
463
497
ColorbarBase.__init__(self, ax, **kw)
464
498
if not CS.filled:
465
499
self.add_lines(CS)
467
kw['cmap'] = mappable.cmap
468
kw['norm'] = mappable.norm
469
501
ColorbarBase.__init__(self, ax, **kw)
477
509
raise ValueError('add_lines is only for a ContourSet of lines')
478
510
tcolors = [c[0] for c in CS.tcolors]
479
511
tlinewidths = [t[0] for t in CS.tlinewidths]
512
# The following was an attempt to get the colorbar lines
513
# to follow subsequent changes in the contour lines,
514
# but more work is needed: specifically, a careful
515
# look at event sequences, and at how
516
# to make one object track another automatically.
517
#tcolors = [col.get_colors()[0] for col in CS.collections]
518
#tlinewidths = [col.get_linewidth()[0] for lw in CS.collections]
519
#print 'tlinewidths:', tlinewidths
480
520
ColorbarBase.add_lines(self, CS.levels, tcolors, tlinewidths)
482
522
def notify(self, mappable):
487
527
cm.ScalarMappable.notify(self, mappable)
488
if self.vmin != self.norm.vmin or self.vmax != self.norm.vmax:
530
#if self.vmin != self.norm.vmin or self.vmax != self.norm.vmax:
491
533
if isinstance(self.mappable, ContourSet):
492
534
CS = self.mappable
493
if self.lines is not None:
494
tcolors = [c[0] for c in CS.tcolors]
495
self.lines.set_color(tcolors)
537
#if self.lines is not None:
538
# tcolors = [c[0] for c in CS.tcolors]
539
# self.lines.set_color(tcolors)
496
540
#Fixme? Recalculate boundaries, ticks if vmin, vmax have changed.
541
#Fixme: Some refactoring may be needed; we should not
542
# be recalculating everything if there was a simple alpha
499
545
def make_axes(parent, **kw):
500
546
orientation = kw.setdefault('orientation', 'vertical')