# We want to draw the shadow for each pie but we will not use "shadow" # option as it does'n save the references to the shadow patches. pies = ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%') for w in pies[0]: # set the id with the label. w.set_gid(w.get_label()) # we don't want to draw the edge of the pie w.set_ec("none") for w in pies[0]: # create shadow patch s = Shadow(w, -0.01, -0.01) s.set_gid(w.get_gid()+"_shadow") s.set_zorder(w.get_zorder() - 0.1) ax.add_patch(s) # save from StringIO import StringIO f = StringIO() plt.savefig(f, format="svg") import xml.etree.cElementTree as ET # filter definition for shadow using a gaussian blur # and lighteneing effect. # The lightnening filter is copied from http://www.w3.org/TR/SVG/filters.html
def pie(self, explode=None, colors=None, autopct=None, pctdistance=0.6, shadow=False): start = time.time() labels = self.pdata.getLabels() if labels[0][0] == "NoLabels": try: self.pdata.initialize(key_type="string") self.pdata.sortLabels() labels = self.pdata.getLabels() nLabels = self.pdata.getNumberOfLabels() explode = [0.0] * nLabels if nLabels > 0: explode[0] = 0.1 except Exception as x: print("PieGraph Error: can not interpret data for the plot") # labels.reverse() values = [l[1] for l in labels] x = numpy.array(values, numpy.float64) self.legendData = labels sx = float(numpy.sum(x)) if sx > 0: x = numpy.divide(x, sx) labels = [l[0] for l in labels] if explode is None: explode = [0] * len(x) assert len(x) == len(labels) assert len(x) == len(explode) plot_axis_labels = self.prefs.get("plot_axis_labels", True) center = 0, 0 radius = 1.1 theta1 = 0 i = 0 texts = [] slices = [] autotexts = [] for frac, label, expl in zip(x, labels, explode): x, y = center theta2 = theta1 + frac thetam = 2 * math.pi * 0.5 * (theta1 + theta2) x += expl * math.cos(thetam) y += expl * math.sin(thetam) color = self.palette.getColor(label) w = Wedge( (x, y), radius, 360.0 * theta1, 360.0 * theta2, facecolor=color, lw=pixelToPoint(0.5, self.dpi), edgecolor="#999999", ) slices.append(w) self.ax.add_patch(w) w.set_label(label) if shadow: # make sure to add a shadow after the call to # add_patch so the figure and transform props will be # set shad = Shadow(w, -0.02, -0.02) shad.set_zorder(0.9 * w.get_zorder()) self.ax.add_patch(shad) if plot_axis_labels: if frac > 0.03: xt = x + 1.05 * radius * math.cos(thetam) yt = y + 1.05 * radius * math.sin(thetam) thetam %= 2 * math.pi if 0 < thetam and thetam < math.pi: valign = "bottom" elif thetam == 0 or thetam == math.pi: valign = "center" else: valign = "top" if thetam > math.pi / 2.0 and thetam < 3.0 * math.pi / 2.0: halign = "right" elif thetam == math.pi / 2.0 or thetam == 3.0 * math.pi / 2.0: halign = "center" else: halign = "left" t = self.ax.text( xt, yt, label, size=pixelToPoint(self.prefs["subtitle_size"], self.dpi), horizontalalignment=halign, verticalalignment=valign, ) t.set_fontname(self.prefs["font"]) t.set_fontsize( pixelToPoint(self.prefs["text_size"], self.dpi)) texts.append(t) if autopct is not None: xt = x + pctdistance * radius * math.cos(thetam) yt = y + pctdistance * radius * math.sin(thetam) if isinstance(autopct, str): s = autopct % (100.0 * frac) elif callable(autopct): s = autopct(100.0 * frac) else: raise TypeError( "autopct must be callable or a format string") t = self.ax.text(xt, yt, s, horizontalalignment="center", verticalalignment="center") t.set_fontname(self.prefs["font"]) t.set_fontsize( pixelToPoint(self.prefs["text_size"], self.dpi)) autotexts.append(t) theta1 = theta2 i += 1 self.legendData.reverse() self.ax.set_xlim((-1.25, 1.25)) self.ax.set_ylim((-1.25, 1.25)) self.ax.set_axis_off() if autopct is None: return slices, texts else: return slices, texts, autotexts
def plot_mix_method(): ''' 这种方法是混合方法,使用外部的SVG。 ''' import matplotlib matplotlib.use("Svg") import matplotlib.pyplot as plt from matplotlib.patches import Shadow fig1 = plt.figure(1, figsize=(6, 6)) ax = fig1.add_axes([0.1, 0.1, 0.8, 0.8]) labels = ['Frogs', 'Hogs', 'Dogs', 'Logs'] fracs = [15, 30, 45, 10] # 百分比 explode = (0, 0.05, 0, 0) pies = ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%') for w in pies[0]: # set the id with the label. w.set_gid(w.get_label()) # we don't want to draw the edge of the pie w.set_ec("none") for w in pies[0]: # create shadow patch s = Shadow(w, -0.01, -0.01) s.set_gid(w.get_gid() + "_shadow") s.set_zorder(w.get_zorder() - 0.1) ax.add_patch(s) # save from io import BytesIO f = BytesIO() plt.savefig(f, format="svg") import xml.etree.cElementTree as ET # filter definition for shadow using a gaussian blur # and lightening effect. # The lightening filter is copied from http://www.w3.org/TR/SVG/filters.html # I tested it with Inkscape and Firefox3. "Gaussian blur" is supported # in both, but the lightening effect only in the Inkscape. Also note # that, Inkscape's exporting also may not support it. filter_def = """ <defs xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'> <filter id='dropshadow' height='1.2' width='1.2'> <feGaussianBlur result='blur' stdDeviation='2'/> </filter> <filter id='MyFilter' filterUnits='objectBoundingBox' x='0' y='0' width='1' height='1'> <feGaussianBlur in='SourceAlpha' stdDeviation='4%' result='blur'/> <feOffset in='blur' dx='4%' dy='4%' result='offsetBlur'/> <feSpecularLighting in='blur' surfaceScale='5' specularConstant='.75' specularExponent='20' lighting-color='#bbbbbb' result='specOut'> <fePointLight x='-5000%' y='-10000%' z='20000%'/> </feSpecularLighting> <feComposite in='specOut' in2='SourceAlpha' operator='in' result='specOut'/> <feComposite in='SourceGraphic' in2='specOut' operator='arithmetic' k1='0' k2='1' k3='1' k4='0'/> </filter> </defs> """ tree, xmlid = ET.XMLID(f.getvalue()) # insert the filter definition in the svg dom tree. tree.insert(0, ET.XML(filter_def)) for i, pie_name in enumerate(labels): pie = xmlid[pie_name] pie.set("filter", 'url(#MyFilter)') shadow = xmlid[pie_name + "_shadow"] shadow.set("filter", 'url(#dropshadow)') fn = "svg_filter_pie.svg" print("Saving '%s'" % fn) ET.ElementTree(tree).write(fn)
def make_graphs(individual_means, individual_means_2): # bar graph compared to average in each category (2 phase bar graph) labels = ['Electricity consumption (kwh * 1000)', '# of flights per year', '# commute miles per year (thousands)', '# of ride sharing trips per year', 'food choice (tons of CO2 emissions/year)'] population_means = [11.698, 2.1, 15, 7.86, 2.5] population_means=list(map(int,population_means)) print(labels) print(individual_means) print(population_means) x = np.arange(len(labels)) # the label locations width = 0.35 # the width of the bars fig, ax = plt.subplots() rects1 = ax.bar(x - width/2, individual_means, width, label='Your score', color='#5dcf60') rects2 = ax.bar(x + width/2, population_means, width, label='Average score', color='#595959') # Add some text for labels, title and custom x-axis tick labels, etc. ax.set_ylabel('Scores') ax.set_title('Scores by label') ax.set_xticks(x) ax.set_xticklabels(labels, rotation='vertical') #rotation='vertical', fontsize='x-small', ax.legend() def autolabel(rects): """Attach a text label above each bar in *rects*, displaying its height.""" for rect in rects: height = rect.get_height() ax.annotate('{}'.format(height), xy=(rect.get_x() + rect.get_width() / 2, height), xytext=(0, 3), # 3 points vertical offset textcoords="offset points", ha='center', va='bottom') autolabel(rects1) autolabel(rects2) fig.tight_layout() # plt.show() plt.savefig('bar.png', format="png") # bar 2 labels = ['electricity', 'flights', 'transportation', 'food', 'retail'] population_means = [7252.76, 602.45, 4515.27, 2267.96, 22.41] population_means=list(map(int,population_means)) individual_means_2=list(map(int, individual_means_2)) print(labels) print(individual_means_2) print(population_means) x = np.arange(len(labels)) # the label locations width = 0.35 # the width of the bars fig, ax = plt.subplots() rects1 = ax.bar(x - width/2, individual_means_2, width, label='Your score', color='#5dcf60') rects2 = ax.bar(x + width/2, population_means, width, label='Average score', color='#595959') # Add some text for labels, title and custom x-axis tick labels, etc. ax.set_ylabel('kg Co2/year') ax.set_title('Scores by label') ax.set_xticks(x) ax.set_xticklabels(labels, rotation='vertical') #rotation='vertical', fontsize='x-small', ax.legend() def autolabel(rects): """Attach a text label above each bar in *rects*, displaying its height.""" for rect in rects: height = rect.get_height() ax.annotate('{}'.format(height), xy=(rect.get_x() + rect.get_width() / 2, height), xytext=(0, 3), # 3 points vertical offset textcoords="offset points", ha='center', va='bottom') autolabel(rects1) autolabel(rects2) fig.tight_layout() # plt.show() plt.savefig('bar_2.png', format="png") # % of contributions to your carbon footpint fig = plt.figure(figsize=(6, 6)) ax = fig.add_axes([0.1, 0.1, 0.8, 0.8]) labels = ['electricitiy', 'flights', 'transport', 'food', 'retail'] fracs = [individual_means_2[0], individual_means_2[1], individual_means_2[2], individual_means_2[3], individual_means_2[4]] colors = ['#5dcf60', '#999999', '#A4efa4', '#595959', '#c3dbc3', '#70b170'] explode = (0, 0, 0, 0, 0) # We want to draw the shadow for each pie but we will not use "shadow" # option as it does'n save the references to the shadow patches. pies = ax.pie(fracs, explode=explode, labels=labels, autopct='%1.1f%%', colors=colors) for w in pies[0]: # set the id with the label. w.set_gid(w.get_label()) # we don't want to draw the edge of the pie w.set_edgecolor("none") for w in pies[0]: # create shadow patch s = Shadow(w, -0.01, -0.01) s.set_gid(w.get_gid() + "_shadow") s.set_zorder(w.get_zorder() - 0.1) ax.add_patch(s) # save plt.savefig('pi.png', format="png")