Skip to content

Commit 63bb757

Browse files
committed
added pie charts
svn path=/trunk/matplotlib/; revision=815
1 parent d391a58 commit 63bb757

File tree

8 files changed

+188
-31
lines changed

8 files changed

+188
-31
lines changed

CHANGELOG

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
New entries should be added at the top
22

3+
2004-12-27 Added pie charts and new example/pie_demo.py
4+
35
2004-12-23 Fixed an agg text rotation alignment bug, fixed some text
46
kwarg processing bugs, and added examples/text_rotation.py
57
to explain and demonstrate how text rotations and alignment

TODO

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
-- DONE with pango : enable anti aliasing for fonts
1717

18-
-- enable fancy text labels (eg, greek letters, math symbols,
18+
-- DONE enable fancy text labels (eg, greek letters, math symbols,
1919
superscripts) ala TeX or unicode
2020

2121
-- DROPPED add a color selection dialog for the background, lines, and text
@@ -25,7 +25,7 @@
2525

2626
-- write a user guide
2727

28-
-- allow more intelligent choice of tick labels and locs when panning and
28+
-- DONE allow more intelligent choice of tick labels and locs when panning and
2929
zooming.
3030

3131
-- figure out why the positioning of dialog boxes based on position
@@ -62,14 +62,13 @@
6262
plot(t1, p1, 'o', t2, p2, ogtt.times, ogtt.cpeptide, 's')
6363

6464

65-
6665
-- DONE xlabel is lower than it needs to be
6766

6867
-- DONE 2003-05-12 Removed some of the state handling of text labels
6968
so they always redraw: interactive setting of x/ylabels doesn't
7069
redraw all labels unless you click a forced redraw
7170

72-
-- When you change a property using the OO interface in interactive,
71+
-- CLOSED When you change a property using the OO interface in interactive,
7372
the figure doesn't know to redraw.
7473

7574
Some possibilities:
@@ -90,8 +89,7 @@
9089
-- DONE 2003-05-12 with window.window.raise_() : raise the figure
9190
returned by figure but don't give it the focus
9291

93-
94-
-- when you toggle an axes for interactive navigation, make sure a
92+
-- CLOSED when you toggle an axes for interactive navigation, make sure a
9593
checked on appears as the default is one is checked
9694

9795
-- DONE compile pygtk for threads on win32.
@@ -109,7 +107,7 @@
109107

110108
-- fix CTRL-z bug in interactive2.py
111109

112-
-- Allow gca not gca(); ditto for gcf()
110+
-- CLOSED Allow gca not gca(); ditto for gcf()
113111

114112
-- DONE Fix legend to take a vector of line handles
115113

@@ -135,7 +133,7 @@
135133

136134
-- DONE 2003-11-20 - make a nice errorbar and scatter screenshot
137135

138-
-- finish contour
136+
-- DONE finish contour
139137

140138
-- allow rectangle select region for zoom tool
141139

@@ -224,8 +222,7 @@
224222

225223
-- DONE decreasing axes - James Boyle <boyle5@llnl.gov>
226224

227-
228-
-- check out Helge's contour
225+
-- CLOSED check out Helge's contour
229226

230227
-- DONE 2004-02-23 with points_to_pixels. fonts too big on wx
231228

@@ -254,7 +251,7 @@
254251

255252
-- DONE integrate numerix chooser with matplotlib.__init__
256253

257-
-- figure out how to make draw if interactive play nicely
254+
-- CLOSED figure out how to make draw if interactive play nicely
258255

259256
-- DONE - (Todd updated docs) - python2.2 no default tkinter
260257

@@ -276,15 +273,15 @@
276273

277274
-- DONE - mathtext size not scaling with DPI
278275

279-
-- implement Paul's mathtext parser fixes
276+
-- CLOSED implement Paul's mathtext parser fixes
280277

281-
-- rotated mathtext
278+
-- DONE rotated mathtext
282279

283280
-- DONE fix mathtext sub and super layout
284281

285282
-- DONE get a sf request to remove fonttools and ttfquery
286283

287-
-- add polar plots
284+
-- DONE add polar plots
288285

289286
-- add pie charts
290287

@@ -306,7 +303,7 @@
306303

307304
-- DONE - text_themes is segfaulting on gtkagg
308305

309-
-- mathtext s l o w
306+
-- DONE mathtext s l o w
310307

311308
-- DONE ps backend fails alignment test
312309

@@ -339,7 +336,7 @@
339336

340337
-- DONE fix color on errorbar lines
341338

342-
-- savefig to file handle.
339+
-- DONE savefig to file handle.
343340

344341
-- add agg and and image generic tostring methods
345342

@@ -455,7 +452,7 @@
455452

456453
-- add wxagg extension code to goals
457454

458-
-- major and minor ticks for log and major and minor grid on/off
455+
-- DONE major and minor ticks for log and major and minor grid on/off
459456

460457
-- make the subplot slider function
461458

@@ -481,7 +478,7 @@
481478

482479
-- DONE add new connect to API_CHANGES
483480

484-
-- port new toolbar to embedding examples
481+
-- DONE port new toolbar to embedding examples
485482

486483
-- DONE \sum height problem - see mathtext_tut
487484

@@ -546,7 +543,6 @@ ZeroDivisionError: SeparableTransformation::eval_scalars yin interval is zero; c
546543
-- tick bug on preserve, possibly center preserved image, flagt to
547544
reshape axes on preserve
548545

549-
550546
-- test rellinks in pydoc
551547

552548
-- port transforms to backend and break up long arrays in agg and svg
@@ -595,13 +591,11 @@ ZeroDivisionError: SeparableTransformation::eval_scalars yin interval is zero; c
595591

596592
-- figure should increment the figure if one already exists
597593

598-
-- majbase and minbase to plot
599-
600-
-- DONE oplot
594+
-- CLOSED oplot
601595

602-
-- override setattr in matlab interface for artists.
596+
-- CLOSED override setattr in matlab interface for artists.
603597

604-
-- cmap observer bug - see
598+
-- DONE cmap observer bug - see
605599
~/python/matplotlib_support/test/cmap_observer_bug.py
606600

607601
-- DONE add connect function.
@@ -616,4 +610,4 @@ ZeroDivisionError: SeparableTransformation::eval_scalars yin interval is zero; c
616610

617611
-- update ticklabels and range for colorbar when clim changes
618612

619-
-- agg rotation bug for angles > 180
613+
-- DONE agg rotation bug for angles > 180

boilerplate.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ def %(func)s(*args, **kwargs):
6161
'loglog',
6262
'pcolor',
6363
'pcolor_classic',
64+
'pie',
6465
'plot',
6566
'plot_date',
6667
'psd',

examples/backend_driver.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
'pcolor_demo.py',
4949
'pcolor_demo2.py',
5050
'pcolor_small.py',
51+
'pie_demo.py',
5152
'polar_demo.py',
5253
'polar_scatter.py',
5354
'psd_demo.py',

examples/dynamic_image_gtkagg.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
z = sin(x) + cos(y)
2121
im = a.imshow( z, cmap=cm.jet)#, interpolation='nearest')
2222

23-
2423
manager = get_current_fig_manager()
2524
cnt = 0
2625
tstart = time.time()

lib/matplotlib/axes.py

Lines changed: 115 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,12 @@
33
import math, sys
44

55
# do not import numerix max! we are using python max.
6-
from numerix import absolute, arange, array, asarray, ones, transpose, \
7-
log, log10, Float, ravel, zeros, Int32, Float64, ceil, indices, \
6+
7+
from numerix import absolute, arange, array, asarray, ones, divide,\
8+
transpose, log, log10, Float, Float32, ravel, zeros,\
9+
Int32, Float64, ceil, indices, \
810
shape, which, where
11+
912
from numerix import max as nxmax
1013
from numerix import min as nxmin
1114
import _contour
@@ -28,7 +31,7 @@
2831

2932
from mlab import meshgrid
3033
from matplotlib import rcParams
31-
from patches import Rectangle, Circle, Polygon, bbox_artist
34+
from patches import Rectangle, Circle, Polygon, Wedge, bbox_artist
3235
from table import Table
3336
from text import Text, _process_text_args
3437
from transforms import Bbox, Point, Value, Affine, NonseparableTransformation
@@ -1974,6 +1977,115 @@ def pcolor_classic(self, *args, **kwargs):
19741977
return patches
19751978

19761979

1980+
def pie(self, x, explode=None, labels=None,
1981+
colors=('b', 'g', 'r', 'c', 'm', 'y', 'k', 'w'),
1982+
autopct=None,
1983+
):
1984+
"""
1985+
Make a pie chart of array x. The fractional area of each wedge is
1986+
given by x/sum(x). If sum(x)<=1, then the values of x give the
1987+
fractional area directly and the array will not be normalized.
1988+
1989+
- explode, if not None, is a len(x) array which specifies the
1990+
fraction of the radius to offset that wedge.
1991+
1992+
- colors is a sequence of matplotlib color args that the pie chart
1993+
will cycle.
1994+
1995+
- labels, if not None, is a len(x) list of labels.
1996+
1997+
- autopct, if not None, is a string or function used to label the
1998+
wedges with their numeric value. The label will be placed inside
1999+
the wedge. If it is a format string, the label will be fmt%pct.
2000+
If it is a function, it will be called
2001+
2002+
The pie chart will probably look best if the figure and axes are
2003+
square. Eg,
2004+
2005+
figure(figsize=(8,8))
2006+
ax = axes([0.1, 0.1, 0.8, 0.8])
2007+
2008+
Return value:
2009+
2010+
If autopct is None, return a list of (patches, texts), where patches
2011+
is a sequence of matplotlib.patches.Wedge instances and texts is a
2012+
list of the label Text instnaces
2013+
2014+
If autopct is not None, return (patches, texts, autotexts), where
2015+
patches and texts are as above, and autotexts is a list of text
2016+
instances for the numeric labels
2017+
"""
2018+
self.set_frame_on(False)
2019+
2020+
x = asarray(x).astype(Float32)
2021+
2022+
sx = float(sum(x))
2023+
if sx>1: x = divide(x,sx)
2024+
2025+
if labels is None: labels = ['']*len(x)
2026+
if explode is None: explode = [0]*len(x)
2027+
assert(len(x)==len(labels))
2028+
assert(len(x)==len(explode))
2029+
2030+
2031+
center = 0,0
2032+
radius = 1
2033+
theta1 = 0
2034+
i = 0
2035+
texts = []
2036+
slices = []
2037+
autotexts = []
2038+
for frac, label, expl in zip(x,labels, explode):
2039+
x, y = center
2040+
theta2 = theta1 + frac
2041+
thetam = 2*math.pi*0.5*(theta1+theta2)
2042+
x += expl*math.cos(thetam)
2043+
y += expl*math.sin(thetam)
2044+
2045+
w = Wedge((x,y), radius, 360.*theta1, 360.*theta2,
2046+
facecolor=colors[i%len(colors)])
2047+
slices.append(w)
2048+
self.add_patch(w)
2049+
self.set_label(label)
2050+
2051+
2052+
xt = x + 1.1*radius*math.cos(thetam)
2053+
yt = y + 1.1*radius*math.sin(thetam)
2054+
2055+
t = self.text(xt, yt, label,
2056+
size=rcParams['tick.labelsize'],
2057+
horizontalalignment='center',
2058+
verticalalignment='center')
2059+
2060+
texts.append(t)
2061+
2062+
if autopct is not None:
2063+
xt = x + 0.6*radius*math.cos(thetam)
2064+
yt = y + 0.6*radius*math.sin(thetam)
2065+
if is_string_like(autopct):
2066+
s = autopct%(100.*frac)
2067+
elif callable(autopct):
2068+
s = autopct(100.*frac)
2069+
else:
2070+
raise TypeError('autopct must be callable or a format string')
2071+
2072+
t = self.text(xt, yt, s,
2073+
horizontalalignment='center',
2074+
verticalalignment='center')
2075+
autotexts.append(t)
2076+
2077+
2078+
theta1 = theta2
2079+
i += 1
2080+
2081+
self.set_xlim((-1.25, 1.25))
2082+
self.set_ylim((-1.25, 1.25))
2083+
self.set_xticks([])
2084+
self.set_yticks([])
2085+
2086+
if autopct is None: return slices, texts
2087+
else: return slices, texts, autotexts
2088+
19772089
def plot(self, *args, **kwargs):
19782090
"""\
19792091
PLOT(*args, **kwargs)

lib/matplotlib/patches.py

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from __future__ import division
2-
2+
import math
33
from matplotlib import rcParams
44
from numerix import array, arange, sin, cos, pi, Float
55
from artist import Artist
@@ -308,7 +308,29 @@ def __init__(self, xy, **kwargs):
308308
def get_verts(self):
309309
return self.xy
310310

311-
311+
312+
class Wedge(Polygon):
313+
def __init__(self, center, r, theta1, theta2,
314+
dtheta=0.1, **kwargs):
315+
"""
316+
Draw a wedge centered at x,y tuple center with radius r that
317+
sweeps theta1 to theta2 (angles)
318+
319+
320+
kwargs are Polygon keyword args
321+
322+
dtheta is the resolution in degrees
323+
324+
"""
325+
xc, yc = center
326+
rads = (math.pi/180.)*arange(theta1, theta2+0.1*dtheta, dtheta)
327+
xs = r*cos(rads)+xc
328+
ys = r*sin(rads)+yc
329+
verts = [center]
330+
verts.extend([(x,y) for x,y in zip(xs,ys)])
331+
332+
Polygon.__init__(self, verts, **kwargs)
333+
312334
class Circle(RegularPolygon):
313335
"""
314336
A circle patch

0 commit comments

Comments
 (0)