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

Commit66290aa

Browse files
committed
Add experimental support for auto-layout of axes on the figure, to
prevent ticks and labels from overlapping things in other axes.svn path=/branches/transforms/; revision=4603
1 parenta2576a7 commit66290aa

File tree

12 files changed

+257
-86
lines changed

12 files changed

+257
-86
lines changed

‎examples/auto_layout.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/usr/bin/env python
2+
"""
3+
Example: simple line plot.
4+
Show how to make and save a simple line plot with labels, title and grid
5+
"""
6+
frompylabimport*
7+
8+
t=arange(0.0,1.0+0.01,0.01)
9+
s=cos(2*2*pi*t)
10+
ax1=subplot(211)
11+
plot(t,s,'-',lw=2)
12+
13+
xlabel('xlabel for bottom axes')
14+
ylabel('ylabel on the right')
15+
title('About as simple as it gets, folks')
16+
grid(True)
17+
ax1.yaxis.set_label_position('right')
18+
ax1.xaxis.set_ticklabels(['Monday','Tuesday','Wednesday','Thursday','Friday'])
19+
forlabelinax1.get_xticklabels():
20+
label.set_rotation(45)
21+
22+
ax2=subplot(212)
23+
plot(t,s,'-',lw=2)
24+
grid(True)
25+
xlabel('xlabel for bottom axes (the ticks are on the top for no good reason)')
26+
ylabel('I\'m a lefty')
27+
ax2.xaxis.set_label_position('bottom')
28+
ax2.xaxis.set_ticks_position('top')
29+
30+
31+
#savefig('simple_plot.png')
32+
savefig('simple_plot')
33+
34+
show()

‎examples/backend_driver.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
'alignment_test.py',
2424
'arctest.py',
2525
'arrow_demo.py',
26+
'auto_layout.py',
2627
'axes_demo.py',
2728
'axhspan_demo.py',
2829
'bar_stacked.py',
@@ -35,7 +36,7 @@
3536
'cohere_demo.py',
3637
'contour_demo.py',
3738
'contourf_demo.py',
38-
'csd_demo.py',
39+
'csd_demo.py',
3940
'custom_ticker1.py',
4041
'customize_rc.py',
4142
'date_demo1.py',

‎examples/colorbar_only.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
# Make a figure and axes with dimensions as desired.
99
fig=pylab.figure(figsize=(8,1.5))
10-
ax=fig.add_axes([0.05,0.4,0.9,0.5])
10+
ax=fig.add_axes([0.05,0.05,0.9,0.9])
1111

1212
# Set the colormap and norm to correspond to the data for which
1313
# the colorbar will be used.

‎examples/figlegend_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python
22

33
frompylabimport*
4-
ax1=axes([0.1,0.1,0.4,0.7])
4+
ax1=axes([0.05,0.1,0.4,0.7])
55
ax2=axes([0.55,0.1,0.4,0.7])
66

77
x=arange(0.0,2.0,0.02)

‎examples/finance_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
raiseSystemExit
2323

2424
fig=figure()
25-
fig.subplots_adjust(bottom=0.2)
25+
#fig.subplots_adjust(bottom=0.2)
2626
ax=fig.add_subplot(111)
2727
ax.xaxis.set_major_locator(mondays)
2828
ax.xaxis.set_minor_locator(alldays)

‎examples/mathtext_demo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
frommatplotlib.pyplotimportfigure,show
88

99
fig=figure()
10-
fig.subplots_adjust(bottom=0.2)
10+
#fig.subplots_adjust(bottom=0.2)
1111

1212
ax=fig.add_subplot(111,axisbg='y')
1313
ax.plot([1,2,3],'r')

‎examples/simple_plot.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
ylabel('voltage (mV)')
1414
title('About as simple as it gets, folks')
1515
grid(True)
16+
axes().xaxis.set_label_position('top')
17+
axes().xaxis.set_ticks_position('top')
18+
axes().yaxis.set_label_position('right')
1619

1720
#savefig('simple_plot.png')
1821
savefig('simple_plot')

‎lib/matplotlib/axes.py

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -770,13 +770,14 @@ def cla(self):
770770

771771
self.grid(self._gridOn)
772772
props=font_manager.FontProperties(size=rcParams['axes.titlesize'])
773+
self.titleOffsetTrans=mtransforms.Affine2D().translate(0.0,10.0)
773774
self.title=mtext.Text(
774-
x=0.5,y=1.02,text='',
775+
x=0.5,y=1.0,text='',
775776
fontproperties=props,
776777
verticalalignment='bottom',
777778
horizontalalignment='center',
778779
)
779-
self.title.set_transform(self.transAxes)
780+
self.title.set_transform(self.transAxes+self.titleOffsetTrans)
780781
self.title.set_clip_box(None)
781782

782783
self._set_artist_props(self.title)
@@ -800,6 +801,8 @@ def cla(self):
800801
self.xaxis.set_clip_path(self.axesPatch)
801802
self.yaxis.set_clip_path(self.axesPatch)
802803

804+
self.titleOffsetTrans.clear()
805+
803806
defclear(self):
804807
'clear the axes'
805808
self.cla()
@@ -905,14 +908,14 @@ def get_data_ratio(self):
905908
ysize=max(math.fabs(ymax-ymin),1e-30)
906909
returnysize/xsize
907910

908-
defapply_aspect(self):
911+
defapply_aspect(self,position):
909912
'''
910913
Use self._aspect and self._adjustable to modify the
911914
axes box or the view limits.
912915
'''
913916
aspect=self.get_aspect()
914917
ifaspect=='auto':
915-
self.set_position(self._originalPosition ,'active')
918+
self.set_position(position ,'active')
916919
return
917920

918921
ifaspect=='equal':
@@ -929,7 +932,7 @@ def apply_aspect(self):
929932
fig_aspect=figH/figW
930933
ifself._adjustable=='box':
931934
box_aspect=A*self.get_data_ratio()
932-
pb=self._originalPosition.frozen()
935+
pb=position.frozen()
933936
pb1=pb.shrunk_to_aspect(box_aspect,pb,fig_aspect)
934937
self.set_position(pb1.anchored(self.get_anchor(),pb),'active')
935938
return
@@ -939,7 +942,7 @@ def apply_aspect(self):
939942
ymin,ymax=self.get_ybound()
940943
ysize=max(math.fabs(ymax-ymin),1e-30)
941944

942-
l,b,w,h=self.get_position(original=True).bounds
945+
l,b,w,h=position.bounds
943946
box_aspect=fig_aspect* (h/w)
944947
data_ratio=box_aspect/A
945948

@@ -1014,7 +1017,7 @@ def axis(self, *v, **kwargs):
10141017
self.set_autoscale_on(True)
10151018
self.set_aspect('auto')
10161019
self.autoscale_view()
1017-
self.apply_aspect()
1020+
#self.apply_aspect()
10181021
ifs=='equal':
10191022
self.set_aspect('equal',adjustable='datalim')
10201023
elifs=='scaled':
@@ -1289,6 +1292,32 @@ def autoscale_view(self, tight=False, scalex=True, scaley=True):
12891292
YL=ylocator.autoscale()
12901293
self.set_ybound(YL)
12911294

1295+
defupdate_layout(self,renderer):
1296+
pad_pixels=rcParams['xtick.major.pad']*self.figure.dpi/72.0
1297+
inverse_transFigure=self.figure.transFigure.inverted()
1298+
t_text,b_text=self.xaxis.get_text_heights(renderer)
1299+
l_text,r_text=self.yaxis.get_text_widths(renderer)
1300+
title_height=self.title.get_window_extent(renderer).height
1301+
title_height+=pad_pixels*2.0
1302+
original_t_text=t_text
1303+
1304+
((l_text,t_text),
1305+
(r_text,b_text),
1306+
(dummy,title_height))=inverse_transFigure.transform(
1307+
((l_text,t_text),
1308+
(r_text,b_text),
1309+
(0.0,title_height)))
1310+
x0,y0,x1,y1=self.get_position(True).extents
1311+
# Adjust the title
1312+
self.titleOffsetTrans.clear().translate(
1313+
0,original_t_text+pad_pixels*2.0)
1314+
1315+
new_position=mtransforms.Bbox.from_extents(
1316+
x0+l_text,y0+b_text,
1317+
x1-r_text,y1-t_text-title_height)
1318+
1319+
self.set_position(new_position,'active')
1320+
12921321
#### Drawing
12931322
defdraw(self,renderer=None,inframe=False):
12941323
"Draw everything (plot lines, axes, labels)"
@@ -1299,7 +1328,8 @@ def draw(self, renderer=None, inframe=False):
12991328
raiseRuntimeError('No renderer defined')
13001329
ifnotself.get_visible():return
13011330
renderer.open_group('axes')
1302-
self.apply_aspect()
1331+
1332+
self.apply_aspect(self.get_position())
13031333

13041334
ifself.axisonandself._frameon:
13051335
self.axesPatch.draw(renderer)

‎lib/matplotlib/axis.py

Lines changed: 84 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,11 @@ def set_pad(self, val):
130130
131131
ACCEPTS: float
132132
"""
133-
self._pad.set(val)
133+
self._pad=val
134134

135135
defget_pad(self,val):
136136
'Get the value of the tick label pad in points'
137-
returnself._pad.get()
137+
returnself._pad
138138

139139
def_get_text1(self):
140140
'Get the default Text 1 instance'
@@ -578,50 +578,74 @@ def _set_artist_props(self, a):
578578
ifaisNone:return
579579
a.set_figure(self.figure)
580580

581-
defdraw(self,renderer,*args,**kwargs):
582-
'Draw the axis lines, grid lines, tick lines and labels'
583-
ifnotself.get_visible():return
584-
renderer.open_group(__name__)
585-
ticklabelBoxes= []
586-
ticklabelBoxes2= []
587-
581+
defiter_ticks(self):
582+
"""
583+
Iterate through all of the major and minor ticks.
584+
"""
588585
majorLocs=self.major.locator()
589586
majorTicks=self.get_major_ticks(len(majorLocs))
590587
self.major.formatter.set_locs(majorLocs)
591588
majorLabels= [self.major.formatter(val,i)fori,valinenumerate(majorLocs)]
592589

590+
minorLocs=self.minor.locator()
591+
minorTicks=self.get_minor_ticks(len(minorLocs))
592+
self.minor.formatter.set_locs(minorLocs)
593+
minorLabels= [self.minor.formatter(val,i)fori,valinenumerate(minorLocs)]
594+
595+
major_minor= [
596+
(majorTicks,majorLocs,majorLabels),
597+
(minorTicks,minorLocs,minorLabels)]
593598

594-
seen= {}
599+
forgroupinmajor_minor:
600+
fortickinzip(*group):
601+
yieldtick
602+
603+
defget_ticklabel_extents(self,renderer):
604+
"""
605+
Get the extents of the tick labels on either side
606+
of the axes.
607+
"""
608+
ticklabelBoxes= []
609+
ticklabelBoxes2= []
595610

596611
interval=self.get_view_interval()
597-
fortick,loc,labelinzip(majorTicks,majorLocs,majorLabels):
612+
fortick,loc,labelinself.iter_ticks():
598613
iftickisNone:continue
599614
ifnotinterval_contains(interval,loc):continue
600-
seen[loc]=1
601615
tick.update_position(loc)
602616
tick.set_label1(label)
603617
tick.set_label2(label)
604-
tick.draw(renderer)
605618
iftick.label1Onandtick.label1.get_visible():
606619
extent=tick.label1.get_window_extent(renderer)
607620
ticklabelBoxes.append(extent)
608621
iftick.label2Onandtick.label2.get_visible():
609622
extent=tick.label2.get_window_extent(renderer)
610623
ticklabelBoxes2.append(extent)
611624

612-
minorLocs=self.minor.locator()
613-
minorTicks=self.get_minor_ticks(len(minorLocs))
614-
self.minor.formatter.set_locs(minorLocs)
615-
minorLabels= [self.minor.formatter(val,i)fori,valinenumerate(minorLocs)]
625+
iflen(ticklabelBoxes):
626+
bbox=Bbox.union(ticklabelBoxes)
627+
else:
628+
bbox=Bbox.from_extents(0,0,0,0)
629+
iflen(ticklabelBoxes2):
630+
bbox2=Bbox.union(ticklabelBoxes2)
631+
else:
632+
bbox2=Bbox.from_extents(0,0,0,0)
633+
returnbbox,bbox2
616634

617-
fortick,loc,labelinzip(minorTicks,minorLocs,minorLabels):
635+
defdraw(self,renderer,*args,**kwargs):
636+
'Draw the axis lines, grid lines, tick lines and labels'
637+
ticklabelBoxes= []
638+
ticklabelBoxes2= []
639+
640+
ifnotself.get_visible():return
641+
renderer.open_group(__name__)
642+
interval=self.get_view_interval()
643+
fortick,loc,labelinself.iter_ticks():
618644
iftickisNone:continue
619645
ifnotinterval_contains(interval,loc):continue
620-
#if seen.has_key(loc): continue
621646
tick.update_position(loc)
622647
tick.set_label1(label)
623648
tick.set_label2(label)
624-
625649
tick.draw(renderer)
626650
iftick.label1Onandtick.label1.get_visible():
627651
extent=tick.label1.get_window_extent(renderer)
@@ -1142,6 +1166,28 @@ def _update_offset_text_position(self, bboxes, bboxes2):
11421166
bottom=bbox.y0
11431167
self.offsetText.set_position((x,bottom-self.OFFSETTEXTPAD*self.figure.dpi/72.0))
11441168

1169+
defget_text_heights(self,renderer):
1170+
"""
1171+
Returns the amount of space one should reserve for text
1172+
above and below the axes. Returns a tuple (above, below)
1173+
"""
1174+
bbox,bbox2=self.get_ticklabel_extents(renderer)
1175+
# MGDTODO: Need a better way to get the pad
1176+
padPixels=self.majorTicks[0]._padPixels
1177+
1178+
above=0.0
1179+
ifbbox2.height:
1180+
above+=bbox2.height+padPixels
1181+
below=0.0
1182+
ifbbox.height:
1183+
below+=bbox.height+padPixels
1184+
1185+
ifself.get_label_position()=='top':
1186+
above+=self.label.get_window_extent(renderer).height+padPixels
1187+
else:
1188+
below+=self.label.get_window_extent(renderer).height+padPixels
1189+
returnabove,below
1190+
11451191
defset_ticks_position(self,position):
11461192
"""
11471193
Set the ticks position (top, bottom, both, default or none)
@@ -1360,6 +1406,24 @@ def set_offset_position(self, position):
13601406
self.offsetText.set_ha(position)
13611407
self.offsetText.set_position((x,y))
13621408

1409+
defget_text_widths(self,renderer):
1410+
bbox,bbox2=self.get_ticklabel_extents(renderer)
1411+
# MGDTODO: Need a better way to get the pad
1412+
padPixels=self.majorTicks[0]._padPixels
1413+
1414+
left=0.0
1415+
ifbbox.width:
1416+
left+=bbox.width+padPixels
1417+
right=0.0
1418+
ifbbox2.width:
1419+
right+=bbox2.width+padPixels
1420+
1421+
ifself.get_label_position()=='left':
1422+
left+=self.label.get_window_extent(renderer).width+padPixels
1423+
else:
1424+
right+=self.label.get_window_extent(renderer).width+padPixels
1425+
returnleft,right
1426+
13631427
defset_ticks_position(self,position):
13641428
"""
13651429
Set the ticks position (left, right, both or default)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp