Skip to content

Commit ef2c9fb

Browse files
committed
Reduce the emitting of object definitions in ps and svg
The cost calculations are very rough, back-of-the-envelope. In the example from matplotlib#3345 I get significant file size reductions: 2.3M before.svg 1.8M after.svg 916K before.ps 672K after.ps
1 parent 878b681 commit ef2c9fb

File tree

2 files changed

+34
-0
lines changed

2 files changed

+34
-0
lines changed

lib/matplotlib/backends/backend_ps.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,23 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
637637
offsets, offsetTrans, facecolors, edgecolors,
638638
linewidths, linestyles, antialiaseds, urls,
639639
offset_position):
640+
# Is the optimization worth it? Rough calculation:
641+
# cost of emitting a path in-line is
642+
# (len_path + 2) * uses_per_path
643+
# cost of definition+use is
644+
# (len_path + 3) + 3 * uses_per_path
645+
len_path = len(paths[0].vertices) if len(paths) > 0 else 0
646+
uses_per_path = self._iter_collection_uses_per_path(
647+
paths, all_transforms, offsets, facecolors, edgecolors)
648+
should_do_optimization = \
649+
len_path + 3 * uses_per_path + 3 < (len_path + 2) * uses_per_path
650+
if not should_do_optimization:
651+
return RendererBase.draw_path_collection(
652+
self, gc, master_transform, paths, all_transforms,
653+
offsets, offsetTrans, facecolors, edgecolors,
654+
linewidths, linestyles, antialiaseds, urls,
655+
offset_position)
656+
640657
write = self._pswriter.write
641658

642659
path_codes = []

lib/matplotlib/backends/backend_svg.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,23 @@ def draw_path_collection(self, gc, master_transform, paths, all_transforms,
607607
offsets, offsetTrans, facecolors, edgecolors,
608608
linewidths, linestyles, antialiaseds, urls,
609609
offset_position):
610+
# Is the optimization worth it? Rough calculation:
611+
# cost of emitting a path in-line is
612+
# (len_path + 5) * uses_per_path
613+
# cost of definition+use is
614+
# (len_path + 3) + 9 * uses_per_path
615+
len_path = len(paths[0].vertices) if len(paths) > 0 else 0
616+
uses_per_path = self._iter_collection_uses_per_path(
617+
paths, all_transforms, offsets, facecolors, edgecolors)
618+
should_do_optimization = \
619+
len_path + 9 * uses_per_path + 3 < (len_path + 5) * uses_per_path
620+
if not should_do_optimization:
621+
return RendererBase.draw_path_collection(
622+
self, gc, master_transform, paths, all_transforms,
623+
offsets, offsetTrans, facecolors, edgecolors,
624+
linewidths, linestyles, antialiaseds, urls,
625+
offset_position)
626+
610627
writer = self.writer
611628
path_codes = []
612629
writer.start('defs')

0 commit comments

Comments
 (0)