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

Commit43a6bd6

Browse files
committed
ENH: Fixed PercentFormatter usage with latex
Added an example to the big formatter exampleAdded test for latex correctnessModified existing pylab example
1 parent1f999f4 commit43a6bd6

File tree

4 files changed

+101
-60
lines changed

4 files changed

+101
-60
lines changed
Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,19 @@
11
importmatplotlib
22
fromnumpy.randomimportrandn
33
importmatplotlib.pyplotasplt
4-
frommatplotlib.tickerimportFuncFormatter
4+
frommatplotlib.tickerimportPercentFormatter
55

66

7-
defto_percent(y,position):
8-
# Ignore the passed in position. This has the effect of scaling the default
9-
# tick locations.
10-
s=str(100*y)
11-
12-
# The percent symbol needs escaping in latex
13-
ifmatplotlib.rcParams['text.usetex']isTrue:
14-
returns+r'$\%$'
15-
else:
16-
returns+'%'
17-
187
x=randn(5000)
198

20-
# Make a normed histogram. It'll be multiplied by 100 later.
21-
plt.hist(x,bins=50,normed=True)
9+
# Create a figure with some axes. This makes it easier to set the
10+
# formatter later, since that is only available through the OO API.
11+
fig,ax=plt.subplots()
2212

23-
# Create the formatter using the function to_percent. This multiplies all the
24-
# default labels by 100, making them all percentages
25-
formatter=FuncFormatter(to_percent)
13+
# Make a normed histogram. It'll be multiplied by 100 later.
14+
plt.hist(x,bins=50,normed=True,axes=ax)
2615

27-
# Set the formatter
28-
plt.gca().yaxis.set_major_formatter(formatter)
16+
# Set the formatter. `xmax` sets the value that maps to 100%.
17+
ax.yaxis.set_major_formatter(PercentFormatter(xmax=1))
2918

3019
plt.show()

‎examples/ticks_and_spines/tick-formatters.py‎

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ def setup(ax):
2121
ax.patch.set_alpha(0.0)
2222

2323

24-
plt.figure(figsize=(8,5))
25-
n=6
24+
plt.figure(figsize=(8,6))
25+
n=7
2626

2727
# Null formatter
2828
ax=plt.subplot(n,1,1)
@@ -87,6 +87,15 @@ def major_formatter(x, pos):
8787
ax.text(0.0,0.1,"StrMethodFormatter('{x}')",
8888
fontsize=15,transform=ax.transAxes)
8989

90+
# Percent formatter
91+
ax=plt.subplot(n,1,7)
92+
setup(ax)
93+
ax.xaxis.set_major_locator(ticker.MultipleLocator(1.00))
94+
ax.xaxis.set_minor_locator(ticker.MultipleLocator(0.25))
95+
ax.xaxis.set_major_formatter(ticker.PercentFormatter(xmax=5))
96+
ax.text(0.0,0.1,"PercentFormatter(xmax=5)",
97+
fontsize=15,transform=ax.transAxes)
98+
9099
# Push the top of the top axes outside the figure because we only show the
91100
# bottom spine.
92101
plt.subplots_adjust(left=0.05,right=0.95,bottom=0.05,top=1.05)

‎lib/matplotlib/tests/test_ticker.py‎

Lines changed: 51 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -510,13 +510,40 @@ def test_basic(self):
510510
tmp_form=mticker.FormatStrFormatter('%05d')
511511
assert'00002'==tmp_form(2)
512512

513-
# test str.format() style formatter
514-
tmp_form=mticker.StrMethodFormatter('{x:05d}')
515-
assert'00002'==tmp_form(2)
516513

517-
# test str.format() style formatter with `pos`
518-
tmp_form=mticker.StrMethodFormatter('{x:03d}-{pos:02d}')
519-
assert'002-01'==tmp_form(2,1)
514+
classTestStrMethodFormatter(object):
515+
test_data= [
516+
('{x:05d}', (2,),'00002'),
517+
('{x:03d}-{pos:02d}', (2,1),'002-01'),
518+
]
519+
520+
@pytest.mark.parametrize('format, input, expected',test_data)
521+
deftest_basic(self,format,input,expected):
522+
fmt=mticker.StrMethodFormatter(format)
523+
assertfmt(*input)==expected
524+
525+
526+
classTestEngFormatter(object):
527+
format_data= [
528+
('',0.1,u'100 m'),
529+
('',1,u'1'),
530+
('',999.9,u'999.9'),
531+
('',1001,u'1.001 k'),
532+
(u's',0.1,u'100 ms'),
533+
(u's',1,u'1 s'),
534+
(u's',999.9,u'999.9 s'),
535+
(u's',1001,u'1.001 ks'),
536+
]
537+
538+
@pytest.mark.parametrize('unit, input, expected',format_data)
539+
deftest_formatting(self,unit,input,expected):
540+
"""
541+
Test the formatting of EngFormatter with some inputs, against
542+
instances with and without units. Cases focus on when no SI
543+
prefix is present, for values in [1, 1000).
544+
"""
545+
fmt=mticker.EngFormatter(unit)
546+
assertfmt(input)==expected
520547

521548

522549
classTestPercentFormatter(object):
@@ -525,12 +552,12 @@ class TestPercentFormatter(object):
525552
(100,0,'%',120,100,'120%'),
526553
(100,0,'%',100,90,'100%'),
527554
(100,0,'%',90,50,'90%'),
528-
(100,0,'%',1.7,40,'2%'),
555+
(100,0,'%',-1.7,40,'-2%'),
529556
(100,1,'%',90.0,100,'90.0%'),
530557
(100,1,'%',80.1,90,'80.1%'),
531558
(100,1,'%',70.23,50,'70.2%'),
532559
# 60.554 instead of 60.55: see https://bugs.python.org/issue5118
533-
(100,1,'%',60.554,40,'60.6%'),
560+
(100,1,'%',-60.554,40,'-60.6%'),
534561
# Check auto decimals over different intervals and values
535562
(100,None,'%',95,1,'95.00%'),
536563
(1.0,None,'%',3,6,'300%'),
@@ -565,33 +592,24 @@ class TestPercentFormatter(object):
565592
'Custom percent symbol',
566593
]
567594

595+
latex_data= [
596+
(False,False,r'50\{t}%'),
597+
(False,True,r'50\\\{t\}\%'),
598+
(True,False,r'50\{t}%'),
599+
(True,True,r'50\{t}%'),
600+
]
601+
568602
@pytest.mark.parametrize(
569603
'xmax, decimals, symbol, x, display_range, expected',
570604
percent_data,ids=percent_ids)
571-
deftest_percentformatter(self,xmax,decimals,symbol,
605+
deftest_basic(self,xmax,decimals,symbol,
572606
x,display_range,expected):
573607
formatter=mticker.PercentFormatter(xmax,decimals,symbol)
574-
assertformatter.format_pct(x,display_range)==expected
575-
576-
577-
classTestEngFormatter(object):
578-
format_data= [
579-
('',0.1,u'100 m'),
580-
('',1,u'1'),
581-
('',999.9,u'999.9'),
582-
('',1001,u'1.001 k'),
583-
(u's',0.1,u'100 ms'),
584-
(u's',1,u'1 s'),
585-
(u's',999.9,u'999.9 s'),
586-
(u's',1001,u'1.001 ks'),
587-
]
588-
589-
@pytest.mark.parametrize('unit, input, expected',format_data)
590-
deftest_formatting(self,unit,input,expected):
591-
"""
592-
Test the formatting of EngFormatter with some inputs, against
593-
instances with and without units. Cases focus on when no SI
594-
prefix is present, for values in [1, 1000).
595-
"""
596-
fmt=mticker.EngFormatter(unit)
597-
assertfmt(input)==expected
608+
withmatplotlib.rc_context(rc={'text.usetex':False}):
609+
assertformatter.format_pct(x,display_range)==expected
610+
611+
@pytest.mark.parametrize('is_latex, usetex, expected',latex_data)
612+
deftest_latex(self,is_latex,usetex,expected):
613+
fmt=mticker.PercentFormatter(symbol='\\{t}%',is_latex=is_latex)
614+
withmatplotlib.rc_context(rc={'text.usetex':usetex}):
615+
assertfmt.format_pct(50,100)==expected

‎lib/matplotlib/ticker.py‎

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1285,16 +1285,19 @@ class PercentFormatter(Formatter):
12851285
situation is where `xmax` is 1.0.
12861286
12871287
`symbol` is a string which will be appended to the label. It may be
1288-
`None` or empty to indicate that no symbol should be used.
1288+
`None` or empty to indicate that no symbol should be used. LaTeX
1289+
special characters are escaped in `symbol` whenever latex mode is
1290+
enabled, unless `is_latex` is `True`.
12891291
12901292
`decimals` is the number of decimal places to place after the point.
12911293
If it is set to `None` (the default), the number will be computed
12921294
automatically.
12931295
"""
1294-
def__init__(self,xmax=100,decimals=None,symbol='%'):
1296+
def__init__(self,xmax=100,decimals=None,symbol='%',is_latex=False):
12951297
self.xmax=xmax+0.0
12961298
self.decimals=decimals
1297-
self.symbol=symbol
1299+
self._symbol=symbol
1300+
self._is_latex=is_latex
12981301

12991302
def__call__(self,x,pos=None):
13001303
"""
@@ -1350,13 +1353,35 @@ def format_pct(self, x, display_range):
13501353
decimals=self.decimals
13511354
s='{x:0.{decimals}f}'.format(x=x,decimals=int(decimals))
13521355

1353-
ifself.symbol:
1354-
returns+self.symbol
1355-
returns
1356+
returns+self.symbol
13561357

13571358
defconvert_to_pct(self,x):
13581359
return100.0* (x/self.xmax)
13591360

1361+
@property
1362+
defsymbol(self):
1363+
"""
1364+
The configured percent symbol as a string.
1365+
1366+
If LaTeX is enabled via ``rcParams['text.usetex']``, the special
1367+
characters `{'#', '$', '%', '&', '~', '_', '^', '\\', '{', '}'}`
1368+
are automatically escaped in the string.
1369+
"""
1370+
symbol=self._symbol
1371+
ifnotsymbol:
1372+
symbol=''
1373+
elifrcParams['text.usetex']andnotself._is_latex:
1374+
# Source: http://www.personal.ceu.hu/tex/specchar.htm
1375+
# Backslash must be first for this to work correctly since
1376+
# it keeps getting added in
1377+
forspecinr'\#$%&~_^{}':
1378+
symbol=symbol.replace(spec,'\\'+spec)
1379+
returnsymbol
1380+
1381+
@symbol.setter
1382+
defsymbol(self):
1383+
self._symbol=symbol
1384+
13601385

13611386
classLocator(TickHelper):
13621387
"""

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp