You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(33) |
Dec
(20) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(7) |
Feb
(44) |
Mar
(51) |
Apr
(43) |
May
(43) |
Jun
(36) |
Jul
(61) |
Aug
(44) |
Sep
(25) |
Oct
(82) |
Nov
(97) |
Dec
(47) |
2005 |
Jan
(77) |
Feb
(143) |
Mar
(42) |
Apr
(31) |
May
(93) |
Jun
(93) |
Jul
(35) |
Aug
(78) |
Sep
(56) |
Oct
(44) |
Nov
(72) |
Dec
(75) |
2006 |
Jan
(116) |
Feb
(99) |
Mar
(181) |
Apr
(171) |
May
(112) |
Jun
(86) |
Jul
(91) |
Aug
(111) |
Sep
(77) |
Oct
(72) |
Nov
(57) |
Dec
(51) |
2007 |
Jan
(64) |
Feb
(116) |
Mar
(70) |
Apr
(74) |
May
(53) |
Jun
(40) |
Jul
(519) |
Aug
(151) |
Sep
(132) |
Oct
(74) |
Nov
(282) |
Dec
(190) |
2008 |
Jan
(141) |
Feb
(67) |
Mar
(69) |
Apr
(96) |
May
(227) |
Jun
(404) |
Jul
(399) |
Aug
(96) |
Sep
(120) |
Oct
(205) |
Nov
(126) |
Dec
(261) |
2009 |
Jan
(136) |
Feb
(136) |
Mar
(119) |
Apr
(124) |
May
(155) |
Jun
(98) |
Jul
(136) |
Aug
(292) |
Sep
(174) |
Oct
(126) |
Nov
(126) |
Dec
(79) |
2010 |
Jan
(109) |
Feb
(83) |
Mar
(139) |
Apr
(91) |
May
(79) |
Jun
(164) |
Jul
(184) |
Aug
(146) |
Sep
(163) |
Oct
(128) |
Nov
(70) |
Dec
(73) |
2011 |
Jan
(235) |
Feb
(165) |
Mar
(147) |
Apr
(86) |
May
(74) |
Jun
(118) |
Jul
(65) |
Aug
(75) |
Sep
(162) |
Oct
(94) |
Nov
(48) |
Dec
(44) |
2012 |
Jan
(49) |
Feb
(40) |
Mar
(88) |
Apr
(35) |
May
(52) |
Jun
(69) |
Jul
(90) |
Aug
(123) |
Sep
(112) |
Oct
(120) |
Nov
(105) |
Dec
(116) |
2013 |
Jan
(76) |
Feb
(26) |
Mar
(78) |
Apr
(43) |
May
(61) |
Jun
(53) |
Jul
(147) |
Aug
(85) |
Sep
(83) |
Oct
(122) |
Nov
(18) |
Dec
(27) |
2014 |
Jan
(58) |
Feb
(25) |
Mar
(49) |
Apr
(17) |
May
(29) |
Jun
(39) |
Jul
(53) |
Aug
(52) |
Sep
(35) |
Oct
(47) |
Nov
(110) |
Dec
(27) |
2015 |
Jan
(50) |
Feb
(93) |
Mar
(96) |
Apr
(30) |
May
(55) |
Jun
(83) |
Jul
(44) |
Aug
(8) |
Sep
(5) |
Oct
|
Nov
(1) |
Dec
(1) |
2016 |
Jan
|
Feb
|
Mar
(1) |
Apr
|
May
|
Jun
(2) |
Jul
|
Aug
(3) |
Sep
(1) |
Oct
(3) |
Nov
|
Dec
|
2017 |
Jan
|
Feb
(5) |
Mar
|
Apr
|
May
|
Jun
|
Jul
(3) |
Aug
|
Sep
(7) |
Oct
|
Nov
|
Dec
|
2018 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(2) |
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
|
|
|
|
|
|
1
|
2
|
3
|
4
(4) |
5
(3) |
6
|
7
|
8
|
9
(2) |
10
(2) |
11
(7) |
12
(3) |
13
|
14
(1) |
15
(1) |
16
|
17
(4) |
18
(1) |
19
|
20
(1) |
21
(1) |
22
|
23
|
24
|
25
(5) |
26
(3) |
27
(4) |
28
(1) |
29
|
30
|
31
|
|
|
|
|
|
>>>>> "Leon" == Leon Brits <leo...@ne...> writes: Leon> I have noticed that there are 10 entries made to the Leon> 'patches'-data for every bargraph I add. Can you explain Leon> this - and/or possibly direct me to a page to read up more Leon> about "_patches". Sure. There are only a few types of objects in matplotlib that appear on the canvas: lines, patches, text and images. patches are things that take up area, like circles and rectangles; the term is borrowed from matlab. Commands like scatter, hist and bar instantiate the kind of patch you need (eg Rectangle or RegularPolygon, both of which derive from the Patch base class in matplotlib.patches) and add it to the axes via Axes.add_patch. The list of patches that have been added to the Axes are stored in a (private) variable self._patches which was not intended to be manipulated by the user (hence the leading underscore and my reference to the solution as a hack). The question is: for dynamic graphs, what is the proper interface to allow you to control, clear, etc, the patches that have been created? The typical way one does dynamic graphs is to fix the objects (be they lines, text or patches) and change the data attributes of those objects (eg x and y locations, height). But your is a special case because there is a fair amount of logic involved in getting the attributes right for stacked bar graphs so it is probably easier to clear the previous patches and add new ones. Would it suffice for you if there was an axes method clear_patches that simply removed all the previous patches you instantiated? The reason I ask is because it is not good practice to write scripts around private attributes which may disappear in a month. JDH
>>>>> "Jared" == Jared Wahlstrand <wah...@um...> writes: Jared> Hi, I wanted to be able to use Inkscape to fiddle with the Jared> details of my plot before exporting it to postscript, so I Jared> started writing an SVG backend. What I have so far is Jared> attached. Note that it's based on matplotlib-0.53.1, so it Jared> won't work with 0.54 yet. So far it just draws lines, Jared> rectangles, polygons, and text (only in helvetica). Jared> Before I go further, I wanted to make sure you or someone Jared> else is not already working on this. If not, I'll port it Jared> to use font-caching, the new transform stuff and figure out Jared> how to draw arcs and polygon collections, etc. This is absolutely great news! Glad to hear you made it so far on your own. I CCd the devel list, which you may want to join, in case anyone else has any advice for you. As far as I know, noone else is working on this. Here are a few thoughts for you when porting to 0.54. All the text layout has been moved to the text.Text front end. So you no longer need to worry about horizontal alignment and the like, compute_offsets is no longer needed, etc.. You also do not need to provide the window extent of text anymore. Just provide get_text_width_height(self, s, prop, ismath) where s is a string and prop is a FontProperties instance. This returns the width and height of the *unrotated* string. In the front end I use this to compute the width and height of the rotated string, compute the alignment offsets, and pass the x,y location to you to draw the rotated string in draw_text. Instead of working with Text instances, as in 0.53, you now work with strings and font properties. The other new Renderer method is get_canvas_width_height As for polygon collections, you can implement this if you want, but the base class provides an implementation that is reasonably fast (approx 5x faster than the prior method of using separate polygon instances). This may be good enough, since my guess is for most cases you only demand the highest performance for interactive use, eg with one of the GUI backends. So the *Agg backends implement this in extension code. As for draw_arc, currently this is only used for drawing circles, so if you implemented draw_circle there is would suffice. Jared> The fact that I, a python novice, could get so far in a day Jared> attests to the awesomeness of matplotlib. Thanks! A day... Amazing. Maybe we'll have you write the PDF backend next :-) JDH from __future__ import division from cStringIO import StringIO from matplotlib.afm import AFM from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\ FigureManagerBase, FigureCanvasBase from matplotlib.cbook import iterable, is_string_like, flatten, enumerate,\ get_recursive_filelist, True, False from matplotlib.figure import Figure from matplotlib.font_manager import fontManager from matplotlib.ft2font import FT2Font from matplotlib._matlab_helpers import Gcf from matplotlib.text import Text from matplotlib.transforms import Bound1D, Bound2D, Transform from matplotlib import rcParams from matplotlib.numerix import fromstring, UInt8, Float32 import binascii import sys,os def error_msg_svg(msg, *args): print >>sys.stderr, 'Error:', msg sys.exit() def _nums_to_str(seq, fmt='%1.3f'): return ' '.join([_int_or_float(val, fmt) for val in seq]) def draw_if_interactive(): pass def show(): """ Show all the figures and enter the gtk mainloop This should be the last line of your script """ for manager in Gcf.get_all_fig_managers(): manager.figure.realize() def new_figure_manager(num, *args): thisFig = Figure(*args) canvas = FigureCanvasSVG(thisFig) manager = FigureManagerSVG(canvas, num) return manager def _rgb_to_hex(rgb): rgbhex='#' for c in rgb: h=hex(int(c*255))[2:] if len(h) < 2: h='0'+ h rgbhex += h return rgbhex class RendererSVG(RendererBase): def __init__(self, svgwriter,width,height): self._svgwriter = svgwriter self.width=width self.height=height def flipy(self): 'return true if y small numbers are top for renderer' return False def draw_rawsvg(self, svg): self._svgwriter.write(svg) def compute_text_offsets(self, t): """ Return the (x,y) offsets to adjust for the alignment specifications """ prop = t.get_font_properties() font = AFM(file(fontManager.findfont(prop, fontext='afm'))) text = t.get_text() l,b,w,h = font.get_str_bbox(text) fontsize = prop.get_size_in_points() w *= 0.001*fontsize h *= 0.001*fontsize halign = t.get_horizontalalignment() valign = t.get_verticalalignment() if t.get_rotation()=='vertical': w, h = h, w if halign=='center': offsetx = w/2 elif halign=='right': offsetx = 0 else: offsetx = w if valign=='center': offsety = h/2 elif valign=='top': offsety = h else: offsety = 0 else: if halign=='center': offsetx = -w/2 elif halign=='right': offsetx = -w else: offsetx = 0 if valign=='center': offsety = h/2 elif valign=='top': offsety = h else: offsety = 0 return (offsetx, offsety) def draw_arc(self, gc, rgbFace, x, y, width, height, angle1, angle2): pass def draw_line(self, gc, x1, y1, x2, y2): """ Draw a single line from x1,y1 to x2,y2 """ type = '<path ' details = ' d=\"M %f,%f L %f,%f\" ' % (x1,self.height-y1,x2,self.height-y2) self._draw_svg(type, details, gc, None) def draw_lines(self, gc, x, y): """ x and y are equal length arrays, draw lines connecting each point in x, y """ if len(x)==0: return if len(x)!=len(y): error_msg_svg('x and y must be the same length') type = '<path ' details =' d=\"M %f,%f ' % (x[0], self.height-y[0]) for tup in zip(x[1:], self.height-y[1:]): details += 'L %f,%f ' % tup details += '\" ' self._draw_svg(type, details, gc, None) def draw_rectangle(self, gc, rgbFace, x, y, width, height): rgbhex='fill:#' for c in rgbFace: rgbhex += hex(int(c*255))[2:] type = '<rect ' details = """ width=\"%f\" height=\"%f\" x=\"%f\" y=\"%f\" """ % (width, height, x, self.height-y-height) self._draw_svg(type, details, gc, rgbFace) def draw_polygon(self, gc, rgbFace, points): type = '<polygon ' details = 'points =\"' for point in points: details += '%f,%f ' % (point[0],self.height-point[1]) details += '\"' self._draw_svg(type, details, gc, rgbFace) def draw_text(self, gc, x, y, t): """ draw a Text instance """ prop = t.get_font_properties() font = AFM(file(fontManager.findfont(prop, fontext='afm'))) text = t.get_text() l,b,w,h = font.get_str_bbox(text) if text=='': return ox, oy = self.compute_text_offsets(t) if t.get_rotation()=='vertical': x = x+ox y = self.height - y+oy-0.001*h else: x = x+ox y = self.height - y+oy thetext = '%s' % text fontname = font.get_fontname() fontsize = prop.get_size_in_points() if t.get_rotation()=='vertical': rotate = '90 rotate' else: rotate = '' svg = '<text ' svg += """\ x=\"%f\" y=\"%f\" style=\"font-size:%f;stroke-width:1.0000000pt;font-family:helvetica;\" > """ % (x,y,float(fontsize)) svg += thetext+' </text>' self.draw_rawsvg(svg) def get_svg(self): return self._svgwriter.getvalue() def finish(self): self._svgwriter.write('</svg>') def new_gc(self): return GraphicsContextSVG() def get_text_extent(self, t): x, y = t.get_xy_display() prop = t.get_font_properties() font = AFM(file(fontManager.findfont(prop, fontext='afm'))) text = t.get_text() l,b,w,h = font.get_str_bbox(text) fontsize = prop.get_size_in_points() l *= 0.001*fontsize b *= 0.001*fontsize w *= 0.001*fontsize h *= 0.001*fontsize ox, oy = self.compute_text_offsets(t) left = x+ox+l bottom = y-oy+b if t.get_rotation()=='vertical': w,h = h,w return Bound2D(left, bottom, w, h) def _draw_svg(self, type, details, gc, rgbFace): svg=type if rgbFace is not None: rgbhex='fill:#' for c in rgbFace: rgbhex += hex(int(c*255))[2:] rgbhex += ';' else: rgbhex='fill:none;' style = self._get_gc_props_svg(gc) svg+=style+rgbhex+ ' \"\n' svg += details svg += ' />\n' self._svgwriter.write(svg) def _get_gc_props_svg(self, gc): color='stroke:'+_rgb_to_hex(gc.get_rgb())+';' linewidth = 'stroke-width:'+repr(gc.get_linewidth())+'pt;' join = 'stroke-linejoin:'+gc.get_joinstyle()+';' cap = 'stroke-linecap:'+gc.get_capstyle()+';' offset, seq = gc.get_dashes() if seq is not None: dashes = 'stroke-dasharray:' for s in seq: dashes += '%d ' % s dashes += ';' dashes += 'stroke-dashoffset:%f;' % offset else: dashes = '' style = 'style=\"'+color+linewidth+join+cap+dashes return style class GraphicsContextSVG(GraphicsContextBase): def set_linestyle(self, style): GraphicsContextBase.set_linestyle(self, style) offset, dashes = self._dashd[style] self.set_dashes(offset, dashes) class FigureCanvasSVG(FigureCanvasBase): def draw(self): pass def print_figure(self, filename, dpi=100, facecolor='w', edgecolor='w', orientation='portrait'): basename, ext = os.path.splitext(filename) if not len(ext): filename += '.svg' self._svgwriter = StringIO() renderer = RendererSVG(self._svgwriter,self.figure.figsize[0]*dpi,self.figure.figsize[1]*dpi) print dpi print (self.figure.figsize[0]*dpi, self.figure.figsize[1]*dpi) self._svgwriter.write(_svgProlog % (renderer.width,renderer.height)) self.figure.draw(renderer) renderer.finish() try: fh = file(filename, 'w') except IOError: error_msg_svg('Could not open %s for writing' % filename) return print >>fh, renderer.get_svg() class FigureManagerSVG(FigureManagerBase): pass FigureManager = FigureManagerSVG error_msg = error_msg_svg _svgProlog = """<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?> <!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\"> <!-- Created with matplotlib (http://matplotlib.sourceforge.net/) --> <svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" version=\"1.0\" x=\"0.0000000\" y=\"0.0000000\" width=\"%f\" height=\"%f\" id=\"svg1\"> """
Thanks for your reply, Problem solved! I am now deleting all '_patches'-data beyond my viewing window's time frame which is set to 60 seconds. I call: if len(ax._patches) > (60*10): del ax._patches[:10] I have noticed that there are 10 entries made to the 'patches'-data for every bargraph I add. Can you explain this - and/or possibly direct me to a page to read up more about "_patches". Thanks for everything Leon On 2004年5月25日 10:29:41 -0500, John Hunter <jdh...@ac...> wrote: >>>>>> "Leon" == Leon Brits <leo...@ne...> writes: > > Leon> Does this help? Should I tell the axes to "not remember" > Leon> the out-of-view data? > > Yes, this appears to be your problem. Normally, I would adivse you to > update the data of your bar elements (patches.Rectangle instances). > This would avoid the overhead of creating all the extra objects. But > for stacked bar graphs this may be more hassle than it's worth. > > But you definitely do need to clear the old instances before adding > the new ones. There are two ways to do this > > ax.cla() # clear all the axes elements > > This might introduce flicker in to your graph so you'll have to test > it. A hack is to simply clear all the patch instances from the axes. > If you are not using other patch building plot commands (eg hist, > scatter, bar) this should work fine and be the fastest solution > > ax._patches = [] > > It might be worthwhile to add a more limited clear function to the > axes. cla clears everything, but in some cases (like this one) you > might just want clear the lines, or the patches, or the text. > > If you are following matplotlib-users, I just did some profiling of > animated graphs and found that text operations were eating up about > 50% of the CPU time on animated graphs. The good news is that the > vast majority of this time can be reclaimed with some fairly easy > optimizations. > > JDH