@@ -87,6 +87,13 @@ def escape_attrib(s):
8787s = s .replace (">" ,">" )
8888return s
8989
90+ def short_float_fmt (x ):
91+ """
92+ Create a short string representation of a float, which is %f
93+ formatting with trailing zeros and the decimal point removed.
94+ """
95+ return '{0:f}' .format (x ).rstrip ('0' ).rstrip ('.' )
96+
9097##
9198# XML writer class.
9299#
@@ -231,7 +238,8 @@ def generate_transform(transform_list=[]):
231238if type == 'matrix' and isinstance (value ,Affine2DBase ):
232239value = value .to_values ()
233240
234- output .write ('%s(%s)' % (type ,' ' .join (str (x )for x in value )))
241+ output .write ('%s(%s)' % (
242+ type ,' ' .join (short_float_fmt (x )for x in value )))
235243return output .getvalue ()
236244return ''
237245
@@ -403,32 +411,32 @@ def _get_style_dict(self, gc, rgbFace):
403411if gc .get_hatch ()is not None :
404412attrib ['fill' ]= "url(#%s)" % self ._get_hatch (gc ,rgbFace )
405413if rgbFace is not None and len (rgbFace )== 4 and rgbFace [3 ]!= 1.0 and not forced_alpha :
406- attrib ['fill-opacity' ]= str (rgbFace [3 ])
414+ attrib ['fill-opacity' ]= short_float_fmt (rgbFace [3 ])
407415else :
408416if rgbFace is None :
409417attrib ['fill' ]= 'none'
410418else :
411419if tuple (rgbFace [:3 ])!= (0 ,0 ,0 ):
412420attrib ['fill' ]= rgb2hex (rgbFace )
413421if len (rgbFace )== 4 and rgbFace [3 ]!= 1.0 and not forced_alpha :
414- attrib ['fill-opacity' ]= str (rgbFace [3 ])
422+ attrib ['fill-opacity' ]= short_float_fmt (rgbFace [3 ])
415423
416424if forced_alpha and gc .get_alpha ()!= 1.0 :
417- attrib ['opacity' ]= str (gc .get_alpha ())
425+ attrib ['opacity' ]= short_float_fmt (gc .get_alpha ())
418426
419427offset ,seq = gc .get_dashes ()
420428if seq is not None :
421- attrib ['stroke-dasharray' ]= ',' .join (['%f' % val for val in seq ])
422- attrib ['stroke-dashoffset' ]= six . text_type (float (offset ))
429+ attrib ['stroke-dasharray' ]= ',' .join ([short_float_fmt ( val ) for val in seq ])
430+ attrib ['stroke-dashoffset' ]= short_float_fmt (float (offset ))
423431
424432linewidth = gc .get_linewidth ()
425433if linewidth :
426434rgb = gc .get_rgb ()
427435attrib ['stroke' ]= rgb2hex (rgb )
428436if not forced_alpha and rgb [3 ]!= 1.0 :
429- attrib ['stroke-opacity' ]= str (rgb [3 ])
437+ attrib ['stroke-opacity' ]= short_float_fmt (rgb [3 ])
430438if linewidth != 1.0 :
431- attrib ['stroke-width' ]= str (linewidth )
439+ attrib ['stroke-width' ]= short_float_fmt (linewidth )
432440if gc .get_joinstyle ()!= 'round' :
433441attrib ['stroke-linejoin' ]= gc .get_joinstyle ()
434442if gc .get_capstyle ()!= 'butt' :
@@ -476,8 +484,12 @@ def _write_clips(self):
476484writer .element ('path' ,d = path_data )
477485else :
478486x ,y ,w ,h = clip
479- writer .element ('rect' ,x = six .text_type (x ),y = six .text_type (y ),
480- width = six .text_type (w ),height = six .text_type (h ))
487+ writer .element (
488+ 'rect' ,
489+ x = short_float_fmt (x ),
490+ y = short_float_fmt (y ),
491+ width = short_float_fmt (w ),
492+ height = short_float_fmt (h ))
481493writer .end ('clipPath' )
482494writer .end ('defs' )
483495
@@ -498,7 +510,8 @@ def _write_svgfonts(self):
498510'font-family' :font .family_name ,
499511'font-style' :font .style_name .lower (),
500512'units-per-em' :'72' ,
501- 'bbox' :' ' .join (six .text_type (x / 64.0 )for x in font .bbox )})
513+ 'bbox' :' ' .join (
514+ short_float_fmt (x / 64.0 )for x in font .bbox )})
502515for char in chars :
503516glyph = font .load_char (char ,flags = LOAD_NO_HINTING )
504517verts ,codes = font .get_path ()
@@ -511,7 +524,8 @@ def _write_svgfonts(self):
511524attrib = {
512525# 'glyph-name': name,
513526'unicode' :unichr (char ),
514- 'horiz-adv-x' :six .text_type (glyph .linearHoriAdvance / 65536.0 )})
527+ 'horiz-adv-x' :
528+ short_float_fmt (glyph .linearHoriAdvance / 65536.0 )})
515529writer .end ('font' )
516530writer .end ('defs' )
517531
@@ -607,8 +621,8 @@ def draw_markers(self, gc, marker_path, marker_trans, path, trans, rgbFace=None)
607621trans_and_flip ,clip = clip ,simplify = False ):
608622if len (vertices ):
609623x ,y = vertices [- 2 :]
610- attrib ['x' ]= six . text_type (x )
611- attrib ['y' ]= six . text_type (y )
624+ attrib ['x' ]= short_float_fmt (x )
625+ attrib ['y' ]= short_float_fmt (y )
612626attrib ['style' ]= self ._get_style (gc ,rgbFace )
613627writer .element ('use' ,attrib = attrib )
614628writer .end ('g' )
@@ -659,8 +673,8 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
659673writer .start ('g' ,attrib = {'clip-path' :'url(#%s)' % clipid })
660674attrib = {
661675'xlink:href' :'#%s' % path_id ,
662- 'x' :six . text_type (xo ),
663- 'y' :six . text_type (self .height - yo ),
676+ 'x' :short_float_fmt (xo ),
677+ 'y' :short_float_fmt (self .height - yo ),
664678'style' :self ._get_style (gc0 ,rgbFace )
665679 }
666680writer .element ('use' ,attrib = attrib )
@@ -729,13 +743,13 @@ def draw_gouraud_triangle(self, gc, points, colors, trans):
729743writer .start (
730744'linearGradient' ,
731745id = "GR%x_%d" % (self ._n_gradients ,i ),
732- x1 = six . text_type (x1 ),y1 = six . text_type (y1 ),
733- x2 = six . text_type (xb ),y2 = six . text_type (yb ))
746+ x1 = short_float_fmt (x1 ),y1 = short_float_fmt (y1 ),
747+ x2 = short_float_fmt (xb ),y2 = short_float_fmt (yb ))
734748writer .element (
735749'stop' ,
736750offset = '0' ,
737751style = generate_css ({'stop-color' :rgb2hex (c ),
738- 'stop-opacity' :six . text_type (c [- 1 ])}))
752+ 'stop-opacity' :short_float_fmt (c [- 1 ])}))
739753writer .element (
740754'stop' ,
741755offset = '1' ,
@@ -746,7 +760,7 @@ def draw_gouraud_triangle(self, gc, points, colors, trans):
746760writer .element (
747761'polygon' ,
748762id = 'GT%x' % self ._n_gradients ,
749- points = " " .join ([six . text_type (x )
763+ points = " " .join ([short_float_fmt (x )
750764for x in (x1 ,y1 ,x2 ,y2 ,x3 ,y3 )]))
751765writer .end ('defs' )
752766
@@ -756,7 +770,7 @@ def draw_gouraud_triangle(self, gc, points, colors, trans):
756770'use' ,
757771attrib = {'xlink:href' :href ,
758772'fill' :rgb2hex (avg_color ),
759- 'fill-opacity' :str (avg_color [- 1 ])})
773+ 'fill-opacity' :short_float_fmt (avg_color [- 1 ])})
760774for i in range (3 ):
761775writer .element (
762776'use' ,
@@ -842,16 +856,16 @@ def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
842856
843857alpha = gc .get_alpha ()
844858if alpha != 1.0 :
845- attrib ['opacity' ]= str (alpha )
859+ attrib ['opacity' ]= short_float_fmt (alpha )
846860
847861attrib ['id' ]= oid
848862
849863if transform is None :
850864self .writer .element (
851865'image' ,
852- x = six . text_type (x / trans [0 ]),
853- y = six . text_type ((self .height - y )/ trans [3 ]- h ),
854- width = six . text_type (w ),height = six . text_type (h ),
866+ x = short_float_fmt (x / trans [0 ]),
867+ y = short_float_fmt ((self .height - y )/ trans [3 ]- h ),
868+ width = short_float_fmt (w ),height = short_float_fmt (h ),
855869attrib = attrib )
856870else :
857871flipped = self ._make_flip_transform (transform )
@@ -864,8 +878,8 @@ def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
864878 [('matrix' ,flipped )])
865879self .writer .element (
866880'image' ,
867- x = six . text_type (x ),y = six . text_type (y ),
868- width = six . text_type (dx ),height = six . text_type (abs (dy )),
881+ x = short_float_fmt (x ),y = short_float_fmt (y ),
882+ width = short_float_fmt (dx ),height = short_float_fmt (abs (dy )),
869883attrib = attrib )
870884
871885if url is not None :
@@ -906,7 +920,7 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
906920if color != '#000000' :
907921style ['fill' ]= color
908922if gc .get_alpha ()!= 1.0 :
909- style ['opacity' ]= six . text_type (gc .get_alpha ())
923+ style ['opacity' ]= short_float_fmt (gc .get_alpha ())
910924
911925if not ismath :
912926font = text2path ._get_font (prop )
@@ -936,9 +950,9 @@ def _draw_text_as_path(self, gc, x, y, s, prop, angle, ismath, mtext=None):
936950for glyph_id ,xposition ,yposition ,scale in glyph_info :
937951attrib = {'xlink:href' :'#%s' % glyph_id }
938952if xposition != 0.0 :
939- attrib ['x' ]= six . text_type (xposition )
953+ attrib ['x' ]= short_float_fmt (xposition )
940954if yposition != 0.0 :
941- attrib ['y' ]= six . text_type (yposition )
955+ attrib ['y' ]= short_float_fmt (yposition )
942956writer .element (
943957'use' ,
944958attrib = attrib )
@@ -1007,7 +1021,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10071021if color != '#000000' :
10081022style ['fill' ]= color
10091023if gc .get_alpha ()!= 1.0 :
1010- style ['opacity' ]= six . text_type (gc .get_alpha ())
1024+ style ['opacity' ]= short_float_fmt (gc .get_alpha ())
10111025
10121026if not ismath :
10131027font = self ._get_font (prop )
@@ -1020,7 +1034,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10201034
10211035attrib = {}
10221036# Must add "px" to workaround a Firefox bug
1023- style ['font-size' ]= six . text_type (fontsize )+ 'px'
1037+ style ['font-size' ]= short_float_fmt (fontsize )+ 'px'
10241038style ['font-family' ]= six .text_type (fontfamily )
10251039style ['font-style' ]= prop .get_style ().lower ()
10261040style ['font-weight' ]= six .text_type (prop .get_weight ()).lower ()
@@ -1048,10 +1062,13 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10481062'center' :'middle' }
10491063style ['text-anchor' ]= ha_mpl_to_svg [mtext .get_ha ()]
10501064
1051- attrib ['x' ]= str (ax )
1052- attrib ['y' ]= str (ay )
1065+ attrib ['x' ]= short_float_fmt (ax )
1066+ attrib ['y' ]= short_float_fmt (ay )
10531067attrib ['style' ]= generate_css (style )
1054- attrib ['transform' ]= "rotate(%f, %f, %f)" % (- angle ,ax ,ay )
1068+ attrib ['transform' ]= "rotate(%s, %s, %s)" % (
1069+ short_float_fmt (- angle ),
1070+ short_float_fmt (ax ),
1071+ short_float_fmt (ay ))
10551072writer .element ('text' ,s ,attrib = attrib )
10561073else :
10571074attrib ['transform' ]= generate_transform ([
@@ -1090,7 +1107,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
10901107spans = {}
10911108for font ,fontsize ,thetext ,new_x ,new_y ,metrics in svg_glyphs :
10921109style = generate_css ({
1093- 'font-size' :six . text_type (fontsize )+ 'px' ,
1110+ 'font-size' :short_float_fmt (fontsize )+ 'px' ,
10941111'font-family' :font .family_name ,
10951112'font-style' :font .style_name .lower (),
10961113'font-weight' :font .style_name .lower ()})
@@ -1120,7 +1137,7 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
11201137
11211138attrib = {
11221139'style' :style ,
1123- 'x' :' ' .join (six . text_type (c [0 ])for c in chars ),
1140+ 'x' :' ' .join (short_float_fmt (c [0 ])for c in chars ),
11241141'y' :ys
11251142 }
11261143
@@ -1135,8 +1152,10 @@ def _draw_text_as_text(self, gc, x, y, s, prop, angle, ismath, mtext=None):
11351152for x ,y ,width ,height in svg_rects :
11361153writer .element (
11371154'rect' ,
1138- x = six .text_type (x ),y = six .text_type (- y + height ),
1139- width = six .text_type (width ),height = six .text_type (height )
1155+ x = short_float_fmt (x ),
1156+ y = short_float_fmt (- y + height ),
1157+ width = short_float_fmt (width ),
1158+ height = short_float_fmt (height )
11401159 )
11411160
11421161writer .end ('g' )