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

Commit5c48c10

Browse files
committed
ENH: colorbar ticks adjustable to colorbar size
1 parentc9f80ef commit5c48c10

File tree

6 files changed

+933
-839
lines changed

6 files changed

+933
-839
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
The ticks for colorbar now adjust for the size of the colorbar
2+
--------------------------------------------------------------
3+
4+
Colorbar ticks now adjust for the size of the colorbar if the
5+
colorbar is made from a mappable that is not a contour or
6+
doesn't have a BoundaryNorm, or boundaries are not specified.
7+
If boundaries, etc are specified, the colorbar maintains the
8+
original behaviour.

‎lib/matplotlib/colorbar.py

Lines changed: 104 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
importsix
2525
fromsix.movesimportxrange,zip
2626

27+
importlogging
2728
importwarnings
2829

2930
importnumpyasnp
@@ -43,6 +44,8 @@
4344

4445
frommatplotlibimportdocstring
4546

47+
_log=logging.getLogger(__name__)
48+
4649
make_axes_kw_doc='''
4750
4851
============= ====================================================
@@ -216,6 +219,22 @@ def _set_ticks_on_axis_warn(*args, **kw):
216219
warnings.warn("Use the colorbar set_ticks() method instead.")
217220

218221

222+
classColorbarAutoLocator(ticker.MaxNLocator):
223+
""" AutoLocator for Colorbar
224+
"""
225+
226+
def__init__(self,colorbar,*args,**kwargs):
227+
self._colorbar=colorbar
228+
nbins='auto'
229+
steps= [1,2,2.5,5,10]
230+
ticker.MaxNLocator.__init__(self,nbins=nbins,steps=steps)
231+
232+
deftick_values(self,vmin,vmax):
233+
vmin=max(vmin,self._colorbar.norm.vmin)
234+
vmax=min(vmax,self._colorbar.norm.vmax)
235+
returnticker.MaxNLocator.tick_values(self,vmin,vmax)
236+
237+
219238
classColorbarBase(cm.ScalarMappable):
220239
'''
221240
Draw a colorbar in an existing axes.
@@ -346,8 +365,15 @@ def draw_all(self):
346365
and do all the drawing.
347366
'''
348367

368+
# sets self._boundaries and self._values in real data units.
369+
# takes into account extend values:
349370
self._process_values()
371+
# sets self.vmin and vmax in data units, but just for
372+
# the part of the colorbar that is not part of the extend
373+
# patch:
350374
self._find_range()
375+
# returns the X and Y mesh, *but* this was/is in normalized
376+
# units:
351377
X,Y=self._mesh()
352378
C=self._values[:,np.newaxis]
353379
self._config_axes(X,Y)
@@ -369,22 +395,76 @@ def config_axis(self):
369395

370396
self._set_label()
371397

398+
def_get_ticker_locator_formatter(self):
399+
locator=self.locator
400+
formatter=self.formatter
401+
iflocatorisNone:
402+
ifself.boundariesisNone:
403+
ifisinstance(self.norm,colors.NoNorm):
404+
nv=len(self._values)
405+
base=1+int(nv/10)
406+
locator=ticker.IndexLocator(base=base,offset=0)
407+
elifisinstance(self.norm,colors.BoundaryNorm):
408+
b=self.norm.boundaries
409+
locator=ticker.FixedLocator(b,nbins=10)
410+
elifisinstance(self.norm,colors.LogNorm):
411+
locator=ticker.LogLocator(subs='all')
412+
elifisinstance(self.norm,colors.SymLogNorm):
413+
# The subs setting here should be replaced
414+
# by logic in the locator.
415+
locator=ticker.SymmetricalLogLocator(
416+
subs=np.arange(1,10),
417+
linthresh=self.norm.linthresh,
418+
base=10)
419+
else:
420+
ifmpl.rcParams['_internal.classic_mode']:
421+
locator=ticker.MaxNLocator()
422+
else:
423+
locator=ColorbarAutoLocator(self)
424+
else:
425+
b=self._boundaries[self._inside]
426+
locator=ticker.FixedLocator(b,nbins=10)
427+
returnlocator,formatter
428+
429+
def_use_adjustable(self):
430+
"""
431+
Return if we should use an adjustable tick locator or a fixed
432+
one. (check is used twice so factored out here...)
433+
"""
434+
return (self.boundariesisNone
435+
andself.valuesisNone
436+
andnotisinstance(self.norm,colors.BoundaryNorm))
437+
372438
defupdate_ticks(self):
373439
"""
374440
Force the update of the ticks and ticklabels. This must be
375441
called whenever the tick locator and/or tick formatter changes.
376442
"""
377443
ax=self.ax
378-
ticks,ticklabels,offset_string=self._ticker()
379-
ifself.orientation=='vertical':
380-
ax.yaxis.set_ticks(ticks)
381-
ax.set_yticklabels(ticklabels)
382-
ax.yaxis.get_major_formatter().set_offset_string(offset_string)
383-
444+
# get the locator and formatter. Defaults to
445+
# self.locator if not None..
446+
locator,formatter=self._get_ticker_locator_formatter()
447+
448+
ifself._use_adjustable():
449+
_log.debug('Using adjustable locator on colorbar')
450+
ifself.orientation=='vertical':
451+
ax.yaxis.set_major_locator(locator)
452+
ax.yaxis.set_major_formatter(formatter)
453+
else:
454+
ax.xaxis.set_major_locator(locator)
455+
ax.xaxis.set_major_formatter(formatter)
384456
else:
385-
ax.xaxis.set_ticks(ticks)
386-
ax.set_xticklabels(ticklabels)
387-
ax.xaxis.get_major_formatter().set_offset_string(offset_string)
457+
_log.debug('Using fixed locator on colorbar')
458+
ticks,ticklabels,offset_string=self._ticker(locator,formatter)
459+
ifself.orientation=='vertical':
460+
ax.yaxis.set_ticks(ticks)
461+
ax.set_yticklabels(ticklabels)
462+
ax.yaxis.get_major_formatter().set_offset_string(offset_string)
463+
464+
else:
465+
ax.xaxis.set_ticks(ticks)
466+
ax.set_xticklabels(ticklabels)
467+
ax.xaxis.get_major_formatter().set_offset_string(offset_string)
388468

389469
defset_ticks(self,ticks,update_ticks=True):
390470
"""
@@ -574,39 +654,12 @@ def add_lines(self, levels, colors, linewidths, erase=True):
574654
self.ax.add_collection(col)
575655
self.stale=True
576656

577-
def_ticker(self):
657+
def_ticker(self,locator,formatter):
578658
'''
579659
Return the sequence of ticks (colorbar data locations),
580660
ticklabels (strings), and the corresponding offset string.
581661
'''
582-
locator=self.locator
583-
formatter=self.formatter
584-
iflocatorisNone:
585-
ifself.boundariesisNone:
586-
ifisinstance(self.norm,colors.NoNorm):
587-
nv=len(self._values)
588-
base=1+int(nv/10)
589-
locator=ticker.IndexLocator(base=base,offset=0)
590-
elifisinstance(self.norm,colors.BoundaryNorm):
591-
b=self.norm.boundaries
592-
locator=ticker.FixedLocator(b,nbins=10)
593-
elifisinstance(self.norm,colors.LogNorm):
594-
locator=ticker.LogLocator(subs='all')
595-
elifisinstance(self.norm,colors.SymLogNorm):
596-
# The subs setting here should be replaced
597-
# by logic in the locator.
598-
locator=ticker.SymmetricalLogLocator(
599-
subs=np.arange(1,10),
600-
linthresh=self.norm.linthresh,
601-
base=10)
602-
else:
603-
ifmpl.rcParams['_internal.classic_mode']:
604-
locator=ticker.MaxNLocator()
605-
else:
606-
locator=ticker.AutoLocator()
607-
else:
608-
b=self._boundaries[self._inside]
609-
locator=ticker.FixedLocator(b,nbins=10)
662+
# locator, formatter = _get_ticker_locator_formatter()
610663
ifisinstance(self.norm,colors.NoNorm)andself.boundariesisNone:
611664
intv=self._values[0],self._values[-1]
612665
else:
@@ -851,12 +904,23 @@ def _mesh(self):
851904
y=self._uniform_y(self._central_N())
852905
else:
853906
y=self._proportional_y()
907+
# if boundaries and values are None, then we can go ahead and
908+
# scale this up for Auto tick location. Otherwise we
909+
# want to keep normalized between 0 and 1 and use manual tick
910+
# locations.
911+
ifself._use_adjustable():
912+
dy=self.vmax-self.vmin
913+
y=y*dy+self.vmin
914+
x=x*dy
915+
else:
916+
dy=1.0
854917
self._y=y
918+
855919
X,Y=np.meshgrid(x,y)
856920
ifself._extend_lower()andnotself.extendrect:
857-
X[0, :]=0.5
921+
X[0, :]=0.5*dy
858922
ifself._extend_upper()andnotself.extendrect:
859-
X[-1, :]=0.5
923+
X[-1, :]=0.5*dy
860924
returnX,Y
861925

862926
def_locate(self,x):
Binary file not shown.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp