|
3 | 3 | import math, sys |
4 | 4 |
|
5 | 5 | # 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, \ |
8 | 10 | shape, which, where |
| 11 | + |
9 | 12 | from numerix import max as nxmax |
10 | 13 | from numerix import min as nxmin |
11 | 14 | import _contour |
|
28 | 31 |
|
29 | 32 | from mlab import meshgrid |
30 | 33 | from matplotlib import rcParams |
31 | | -from patches import Rectangle, Circle, Polygon, bbox_artist |
| 34 | +from patches import Rectangle, Circle, Polygon, Wedge, bbox_artist |
32 | 35 | from table import Table |
33 | 36 | from text import Text, _process_text_args |
34 | 37 | from transforms import Bbox, Point, Value, Affine, NonseparableTransformation |
@@ -1974,6 +1977,115 @@ def pcolor_classic(self, *args, **kwargs): |
1974 | 1977 | return patches |
1975 | 1978 |
|
1976 | 1979 |
|
| 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 | + |
1977 | 2089 | def plot(self, *args, **kwargs): |
1978 | 2090 | """\ |
1979 | 2091 | PLOT(*args, **kwargs) |
|
0 commit comments