Skip to content

Commit 2f9aa9e

Browse files
committed
fixed dpi figure title positioning problem
svn path=/trunk/matplotlib/; revision=5076
1 parent 019e303 commit 2f9aa9e

File tree

7 files changed

+99
-45
lines changed

7 files changed

+99
-45
lines changed

CODING_GUIDE

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ in mind.
4545

4646
For numpy, use:
4747

48-
import numpy as npy
49-
a = npy.array([1,2,3])
48+
import numpy as np
49+
a = np.array([1,2,3])
5050

5151

5252
For masked arrays, use:

Makefile

+5-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ DISTFILES = API_CHANGES KNOWN_BUGS INSTALL README TODO license \
1010
RELEASE = matplotlib-${VERSION}
1111

1212

13-
clean:
13+
clean:
1414
${PYTHON} setup.py clean;\
1515
rm -f *.png *.ps *.eps *.svg *.jpg *.pdf
1616
find . -name "_tmp*.py" | xargs rm -f;\
@@ -25,11 +25,12 @@ release: ${DISTFILES}
2525
${PYTHON} license.py ${VERSION} license/LICENSE;\
2626
${PYTHON} setup.py sdist --formats=gztar,zip;
2727

28-
pyback:
29-
tar cvfz pyback.tar.gz *.py lib src examples/*.py unit/*.py
30-
28+
pyback:
29+
tar cvfz pyback.tar.gz *.py lib src examples/*.py unit/*.py
3130

3231

32+
build_osx105:
33+
CFLAGS="-Os -arch i386 -arch ppc" LDFLAGS="-Os -arch i386 -arch ppc" python setup.py build
3334

3435

3536

examples/barchart_demo.py

+25-10
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,39 @@
1+
12
#!/usr/bin/env python
23
# a bar plot with errorbars
3-
from pylab import *
4+
import numpy as np
5+
import matplotlib.pyplot as plt
46

57
N = 5
68
menMeans = (20, 35, 30, 35, 27)
79
menStd = (2, 3, 4, 1, 2)
810

9-
ind = arange(N) # the x locations for the groups
11+
ind = np.arange(N) # the x locations for the groups
1012
width = 0.35 # the width of the bars
11-
p1 = bar(ind, menMeans, width, color='r', yerr=menStd)
13+
14+
fig = plt.figure()
15+
ax = fig.add_subplot(111)
16+
rects1 = ax.bar(ind, menMeans, width, color='r', yerr=menStd)
1217

1318
womenMeans = (25, 32, 34, 20, 25)
1419
womenStd = (3, 5, 2, 3, 3)
15-
p2 = bar(ind+width, womenMeans, width, color='y', yerr=womenStd)
20+
rects2 = ax.bar(ind+width, womenMeans, width, color='y', yerr=womenStd)
21+
22+
# add some
23+
ax.set_ylabel('Scores')
24+
ax.set_title('Scores by group and gender')
25+
ax.set_xticks(ind+width, ('G1', 'G2', 'G3', 'G4', 'G5') )
1626

17-
ylabel('Scores')
18-
title('Scores by group and gender')
19-
xticks(ind+width, ('G1', 'G2', 'G3', 'G4', 'G5') )
27+
ax.legend( (rects1[0], rects2[0]), ('Men', 'Women') )
2028

21-
legend( (p1[0], p2[0]), ('Men', 'Women') )
29+
def autolabel(rects):
30+
# attach some text labels
31+
for rect in rects:
32+
height = rect.get_height()
33+
ax.text(rect.get_x()+rect.get_width()/2., 1.05*height, '%d'%int(height),
34+
ha='center', va='bottom')
2235

23-
#savefig('barchart_demo')
24-
show()
36+
autolabel(rects1)
37+
autolabel(rects2)
38+
#fig.savefig('barchart_demo')
39+
plt.show()

lib/matplotlib/axes.py

+18-4
Original file line numberDiff line numberDiff line change
@@ -780,7 +780,10 @@ def cla(self):
780780

781781
self.grid(self._gridOn)
782782
props = font_manager.FontProperties(size=rcParams['axes.titlesize'])
783-
self.titleOffsetTrans = mtransforms.Affine2D().translate(0.0, 10.0)
783+
784+
785+
self.titleOffsetTrans = mtransforms.Affine2D().translate(
786+
0.0, 5.0*self.figure.dpi/72.)
784787
self.title = mtext.Text(
785788
x=0.5, y=1.0, text='',
786789
fontproperties=props,
@@ -811,7 +814,16 @@ def cla(self):
811814
self.xaxis.set_clip_path(self.axesPatch)
812815
self.yaxis.set_clip_path(self.axesPatch)
813816

814-
self.titleOffsetTrans.clear().translate(0.0, 10.0)
817+
self.titleOffsetTrans.clear().translate(
818+
0.0, 5.0*self.figure.dpi/72.)
819+
820+
def on_dpi_change(fig):
821+
self.titleOffsetTrans.clear().translate(
822+
0.0, 5.0*fig.dpi/72.)
823+
824+
self.figure.callbacks.connect('dpi_changed', on_dpi_change)
825+
826+
815827

816828
def clear(self):
817829
'clear the axes'
@@ -839,8 +851,10 @@ def hold(self, b=None):
839851
figure will be cleared on the next plot command
840852
841853
"""
842-
if b is None: self._hold = not self._hold
843-
else: self._hold = b
854+
if b is None:
855+
self._hold = not self._hold
856+
else:
857+
self._hold = b
844858

845859
def get_aspect(self):
846860
return self._aspect

lib/matplotlib/figure.py

+21-6
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"""
22
Figure class -- add docstring here!
33
"""
4-
import numpy as npy
4+
import numpy as np
55
import time
66

77
import artist
@@ -20,6 +20,8 @@
2020
from projections import projection_factory, get_projection_names, \
2121
get_projection_class
2222

23+
import matplotlib.cbook as cbook
24+
2325
class SubplotParams:
2426
"""
2527
A class to hold the parameters for a subplot
@@ -176,6 +178,13 @@ def __call__(self, n=1, timeout=30, verbose=False, show_clicks=True):
176178

177179
class Figure(Artist):
178180

181+
"""
182+
The Figure instance supports callbacks through a callbacks
183+
attribute which is a cbook.CallbackRegistry instance. The events
184+
you can connect to are 'dpi_changed', and the callback will be
185+
called with func(fig) where fig is the Figure instance
186+
"""
187+
179188
def __str__(self):
180189
return "Figure(%gx%g)" % tuple(self.bbox.size)
181190

@@ -195,6 +204,8 @@ def __init__(self,
195204
"""
196205
Artist.__init__(self)
197206

207+
self.callbacks = cbook.CallbackRegistry(('dpi_changed', ))
208+
198209
if figsize is None : figsize = rcParams['figure.figsize']
199210
if dpi is None : dpi = rcParams['figure.dpi']
200211
if facecolor is None: facecolor = rcParams['figure.facecolor']
@@ -236,6 +247,7 @@ def _get_dpi(self):
236247
def _set_dpi(self, dpi):
237248
self._dpi = dpi
238249
self.dpi_scale_trans.clear().scale(dpi, dpi)
250+
self.callbacks.process('dpi_changed', self)
239251
dpi = property(_get_dpi, _set_dpi)
240252

241253
def enable_auto_layout(self, setting=True):
@@ -255,7 +267,7 @@ def autofmt_xdate(self, bottom=0.2, rotation=30, ha='right'):
255267
rotation: the rotation of the xtick labels
256268
ha : the horizontal alignment of the xticklabels
257269
"""
258-
allsubplots = npy.alltrue([hasattr(ax, 'is_last_row') for ax in self.axes])
270+
allsubplots = np.alltrue([hasattr(ax, 'is_last_row') for ax in self.axes])
259271
if len(self.axes)==1:
260272
for label in ax.get_xticklabels():
261273
label.set_ha(ha)
@@ -662,6 +674,9 @@ def clf(self):
662674
"""
663675
Clear the figure
664676
"""
677+
678+
self.callbacks = cbook.CallbackRegistry(('dpi_changed', ))
679+
665680
for ax in tuple(self.axes): # Iterate over the copy.
666681
ax.cla()
667682
self.delaxes(ax) # removes ax from self.axes
@@ -1022,8 +1037,8 @@ def figaspect(arg):
10221037

10231038
# min/max sizes to respect when autoscaling. If John likes the idea, they
10241039
# could become rc parameters, for now they're hardwired.
1025-
figsize_min = npy.array((4.0,2.0)) # min length for width/height
1026-
figsize_max = npy.array((16.0,16.0)) # max length for width/height
1040+
figsize_min = np.array((4.0,2.0)) # min length for width/height
1041+
figsize_max = np.array((16.0,16.0)) # max length for width/height
10271042
#figsize_min = rcParams['figure.figsize_min']
10281043
#figsize_max = rcParams['figure.figsize_max']
10291044

@@ -1038,7 +1053,7 @@ def figaspect(arg):
10381053
fig_height = rcParams['figure.figsize'][1]
10391054

10401055
# New size for the figure, keeping the aspect ratio of the caller
1041-
newsize = npy.array((fig_height/arr_ratio,fig_height))
1056+
newsize = np.array((fig_height/arr_ratio,fig_height))
10421057

10431058
# Sanity checks, don't drop either dimension below figsize_min
10441059
newsize /= min(1.0,*(newsize/figsize_min))
@@ -1048,7 +1063,7 @@ def figaspect(arg):
10481063

10491064
# Finally, if we have a really funky aspect ratio, break it but respect
10501065
# the min/max dimensions (we don't want figures 10 feet tall!)
1051-
newsize = npy.clip(newsize,figsize_min,figsize_max)
1066+
newsize = np.clip(newsize,figsize_min,figsize_max)
10521067
return newsize
10531068

10541069
artist.kwdocd['Figure'] = artist.kwdoc(Figure)

lib/matplotlib/pyplot.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,9 @@ def savefig(*args, **kwargs):
274274

275275
def ginput(*args, **kwargs):
276276
"""
277-
Blocking call to interact with the figure.
277+
Blocking call to interact with the figure.
278278
279-
This will wait for n clicks from the user and return a list of the
279+
This will wait for n clicks from the user and return a list of the
280280
coordinates of each click.
281281
282282
If timeout is negative, does not timeout.
@@ -345,8 +345,17 @@ def hold(b=None):
345345
will be cleared on the next plot command
346346
"""
347347

348-
gcf().hold(b)
349-
gca().hold(b)
348+
fig = gcf()
349+
ax = fig.gca()
350+
351+
fig.hold(b)
352+
ax.hold(b)
353+
354+
# b=None toggles the hold state, so let's get get the current hold
355+
# state; but should pyplot hold toggle the rc setting - me thinks
356+
# not
357+
b = ax.ishold()
358+
350359
rc('axes', hold=b)
351360

352361
def ishold():

lib/matplotlib/text.py

+15-15
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from __future__ import division
55
import math
66

7-
import numpy as npy
7+
import numpy as np
88

99
from matplotlib import cbook
1010
from matplotlib import rcParams
@@ -180,8 +180,8 @@ def _get_layout(self, renderer):
180180
width, height = 0.0, 0.0
181181
lines = self._text.split('\n')
182182

183-
whs = npy.zeros((len(lines), 2))
184-
horizLayout = npy.zeros((len(lines), 4))
183+
whs = np.zeros((len(lines), 2))
184+
horizLayout = np.zeros((len(lines), 4))
185185

186186
# Find full vertical extent of font,
187187
# including ascenders and descenders:
@@ -208,7 +208,7 @@ def _get_layout(self, renderer):
208208
# get the rotation matrix
209209
M = Affine2D().rotate_deg(self.get_rotation())
210210

211-
offsetLayout = npy.zeros((len(lines), 2))
211+
offsetLayout = np.zeros((len(lines), 2))
212212
offsetLayout[:] = horizLayout[:, 0:2]
213213
# now offset the individual text lines within the box
214214
if len(lines)>1: # do the multiline aligment
@@ -219,9 +219,9 @@ def _get_layout(self, renderer):
219219
offsetLayout[:, 0] += width - horizLayout[:, 2]
220220

221221
# the corners of the unrotated bounding box
222-
cornersHoriz = npy.array(
222+
cornersHoriz = np.array(
223223
[(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin)],
224-
npy.float_)
224+
np.float_)
225225
# now rotate the bbox
226226
cornersRotated = M.transform(cornersHoriz)
227227

@@ -658,7 +658,7 @@ class TextWithDash(Text):
658658
dashlength is the length of the dash in canvas units.
659659
(default=0.0).
660660
661-
dashdirection is one of 0 or 1, npy.where 0 draws the dash
661+
dashdirection is one of 0 or 1, np.where 0 draws the dash
662662
after the text and 1 before.
663663
(default=0).
664664
@@ -782,15 +782,15 @@ def update_coords(self, renderer):
782782
dashpush = self.get_dashpush()
783783

784784
angle = get_rotation(dashrotation)
785-
theta = npy.pi*(angle/180.0+dashdirection-1)
786-
cos_theta, sin_theta = npy.cos(theta), npy.sin(theta)
785+
theta = np.pi*(angle/180.0+dashdirection-1)
786+
cos_theta, sin_theta = np.cos(theta), np.sin(theta)
787787

788788
transform = self.get_transform()
789789

790790
# Compute the dash end points
791791
# The 'c' prefix is for canvas coordinates
792792
cxy = transform.transform_point((dashx, dashy))
793-
cd = npy.array([cos_theta, sin_theta])
793+
cd = np.array([cos_theta, sin_theta])
794794
c1 = cxy+dashpush*cd
795795
c2 = cxy+(dashpush+dashlength)*cd
796796

@@ -829,8 +829,8 @@ def update_coords(self, renderer):
829829
if dy > h or dy < -h:
830830
dy = h
831831
dx = h/tan_theta
832-
cwd = npy.array([dx, dy])/2
833-
cwd *= 1+dashpad/npy.sqrt(npy.dot(cwd,cwd))
832+
cwd = np.array([dx, dy])/2
833+
cwd *= 1+dashpad/np.sqrt(np.dot(cwd,cwd))
834834
cw = c2+(dashdirection*2-1)*cwd
835835

836836
newx, newy = inverse.transform_point(tuple(cw))
@@ -840,7 +840,7 @@ def update_coords(self, renderer):
840840
# I'm not at all sure this is the right way to do this.
841841
we = Text.get_window_extent(self, renderer=renderer)
842842
self._twd_window_extent = we.frozen()
843-
self._twd_window_extent.update_from_data_xy(npy.array([c1]), False)
843+
self._twd_window_extent.update_from_data_xy(np.array([c1]), False)
844844

845845
# Finally, make text align center
846846
Text.set_horizontalalignment(self, 'center')
@@ -1094,8 +1094,8 @@ def _get_xy(self, x, y, s):
10941094
return x, y
10951095
elif s=='polar':
10961096
theta, r = x, y
1097-
x = r*npy.cos(theta)
1098-
y = r*npy.sin(theta)
1097+
x = r*np.cos(theta)
1098+
y = r*np.cosmsin(theta)
10991099
trans = self.axes.transData
11001100
return trans.transform_point((x,y))
11011101
elif s=='figure points':

0 commit comments

Comments
 (0)