From 61ce23ce7e2e84e741566f8cf841b2b78ccdcf32 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Fri, 11 Apr 2025 00:53:12 -0500 Subject: [PATCH] scripts: maps: Fixed some aspect ratio issues, limited scope Replacing -R/--aspect-ratio, --to-ratio now calculates the width/height _before_ adding decoration such as headers, stack info, etc. I toying around with generalizing -R/--aspect-ratio to include decorations, but when Wolfram Alpha spit this mess for the post-header formula: header*r - sqrt(4*v*r + padding^2*r) w = ------------------------------------ 2 I decided maybe a generalized -R/--aspect-ratio is a _bit_ too complicated for what are supposed to be small standalone Python scripts... --- Also fixed the scaling formula, which should've taken the sqrt _after_ multiplying by the aspect ratio: w = sqrt(v*r) I only noticed while trying to solve for the more complicated post-decoration formula, the difference is pretty minor. --- scripts/codemap.py | 56 ++++++++++++++-------------------- scripts/codemapd3.py | 71 ++++++++++++++++++++----------------------- scripts/dbgbmap.py | 26 ++++++++++------ scripts/dbgbmapd3.py | 28 +++++++++++------ scripts/tracebd.py | 26 ++++++++++------ scripts/treemap.py | 72 ++++++++++++++++++-------------------------- scripts/treemapd3.py | 52 ++++++++++++++++++++------------ 7 files changed, 170 insertions(+), 161 deletions(-) diff --git a/scripts/codemap.py b/scripts/codemap.py index 1c367717..f2f1b68d 100755 --- a/scripts/codemap.py +++ b/scripts/codemap.py @@ -781,7 +781,7 @@ def partition_dice(children, total, x, y, width, height): y_ += t.height def partition_squarify(children, total, x, y, width, height, *, - aspect_ratio=(1,1)): + aspect_ratio=1/1): # this algorithm is described here: # https://www.win.tue.nl/~vanwijk/stm.pdf i = 0 @@ -792,8 +792,7 @@ def partition_squarify(children, total, x, y, width, height, *, height_ = height # note we don't really care about width vs height until # actually slicing - ratio = max(aspect_ratio[0] / aspect_ratio[1], - aspect_ratio[1] / aspect_ratio[0]) + ratio = max(aspect_ratio, 1/aspect_ratio) while i < len(children): # calculate initial aspect ratio @@ -910,7 +909,7 @@ def main_(f, paths, *, height=None, no_header=False, to_scale=None, - aspect_ratio=(1,1), + to_ratio=1/1, tiny=False, title=None, padding=0, @@ -1196,33 +1195,23 @@ def main_(f, paths, *, else totals.get('frame', 0) if not nil_frames else totals.get('ctx', 0)) if total_value: - # scale if needed - if braille: - xscale, yscale = 2, 4 - elif dots: - xscale, yscale = 1, 2 - else: - xscale, yscale = 1, 1 + # don't include header in scale + width__ = width_ + height__ = height_ - (1 if not no_header else 0) # scale width only if height is not None: - width_ = mt.ceil( - ((total_value * to_scale) / (height_*yscale)) - / xscale) + width__ = mt.ceil((total_value * to_scale) / max(height__, 1)) # scale height only elif width is not None: - height_ = mt.ceil( - ((total_value * to_scale) / (width_*xscale)) - / yscale) + height__ = mt.ceil((total_value * to_scale) / max(width__, 1)) # scale based on aspect-ratio else: - width_ = mt.ceil( - (mt.sqrt(total_value * to_scale) - * (aspect_ratio[0] / aspect_ratio[1])) - / xscale) - height_ = mt.ceil( - ((total_value * to_scale) / (width_*xscale)) - / yscale) + width__ = mt.ceil(mt.sqrt(total_value * to_scale * to_ratio)) + height__ = mt.ceil((total_value * to_scale) / max(width__, 1)) + + width_ = width__ + height_ = height__ + (1 if not no_header else 0) # as a special case, if height is implicit and we have nothing to # show, don't print anything @@ -1278,11 +1267,12 @@ def main_(f, paths, *, or args.get('rectify')): partition_squarify(tile.children, tile.value, x__, y__, width__, height__, - aspect_ratio=(args['squarify_ratio'], 1) + aspect_ratio=( + args['squarify_ratio'] if args.get('squarify_ratio') - else (width_, height_) + else width_/height_ if args.get('rectify') - else (1, 1)) + else 1/1)) else: # default to binary partitioning partition_binary(tile.children, tile.value, @@ -1608,8 +1598,8 @@ if __name__ == "__main__": type=lambda x: ( (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) if ':' in x else float(x)), - help="Specify an explicit ratio for the squarify algorithm. " - "Implies --squarify.") + help="Specify an explicit aspect ratio for the squarify " + "algorithm. Implies --squarify.") parser.add_argument( '--to-scale', nargs='?', @@ -1617,13 +1607,13 @@ if __name__ == "__main__": (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) if ':' in x else float(x)), const=1, - help="Scale the resulting treemap such that 1 pixel ~= 1/scale " + help="Scale the resulting treemap such that 1 char ~= 1/scale " "units. Defaults to scale=1. ") parser.add_argument( - '-R', '--aspect-ratio', + '--to-ratio', type=lambda x: ( - tuple(float(v) for v in x.split(':', 1)) - if ':' in x else (float(x), 1)), + (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) + if ':' in x else float(x)), help="Aspect ratio to use with --to-scale. Defaults to 1:1.") parser.add_argument( '-t', '--tiny', diff --git a/scripts/codemapd3.py b/scripts/codemapd3.py index 0bf20adc..39a61e77 100755 --- a/scripts/codemapd3.py +++ b/scripts/codemapd3.py @@ -501,7 +501,7 @@ def partition_dice(children, total, x, y, width, height): y_ += t.height def partition_squarify(children, total, x, y, width, height, *, - aspect_ratio=(1,1)): + aspect_ratio=1/1): # this algorithm is described here: # https://www.win.tue.nl/~vanwijk/stm.pdf i = 0 @@ -512,8 +512,7 @@ def partition_squarify(children, total, x, y, width, height, *, height_ = height # note we don't really care about width vs height until # actually slicing - ratio = max(aspect_ratio[0] / aspect_ratio[1], - aspect_ratio[1] / aspect_ratio[0]) + ratio = max(aspect_ratio, 1/aspect_ratio) while i < len(children): # calculate initial aspect ratio @@ -637,7 +636,7 @@ def main(paths, output, *, mode_callees=False, mode_callers=False, to_scale=None, - aspect_ratio=(1,1), + to_ratio=1/1, title=None, padding=1, no_label=False, @@ -993,36 +992,31 @@ def main(paths, output, *, else totals.get('frame', 0) if not nil_frames else totals.get('ctx', 0)) if total_value: + # don't include header/stack in scale + width__ = width_ + height__ = height_ + if not no_header: + height__ -= mt.ceil(FONT_SIZE * 1.3) + if not no_stack: + width__ *= (1 - stack_ratio) + # scale width only if height is not None: - if not no_stack: - width_ = mt.ceil(((total_value * to_scale) / height_) - # add space for stack - / (1 - stack_ratio)) - else: - width_ = mt.ceil((total_value * to_scale) / height_) + width__ = mt.ceil((total_value * to_scale) / max(height__, 1)) # scale height only elif width is not None: - if not no_stack: - height_ = mt.ceil((total_value * to_scale) - # carve out space for stack - / (width_ * (1 - stack_ratio))) - else: - height_ = mt.ceil((total_value * to_scale) / width_) + height__ = mt.ceil((total_value * to_scale) / max(width__, 1)) # scale based on aspect-ratio else: - if not no_stack: - width_ = mt.ceil(mt.sqrt(total_value * to_scale) - * (aspect_ratio[0] / aspect_ratio[1]) - # add space for stack - / (1 - stack_ratio)) - height_ = mt.ceil((total_value * to_scale) - # carve out space for stack - / (width_ * (1 - stack_ratio))) - else: - width_ = mt.ceil(mt.sqrt(total_value * to_scale) - * (aspect_ratio[0] / aspect_ratio[1])) - height_ = mt.ceil((total_value * to_scale) / width_) + width__ = mt.ceil(mt.sqrt(total_value * to_scale * to_ratio)) + height__ = mt.ceil((total_value * to_scale) / max(width__, 1)) + + if not no_stack: + width__ /= (1 - stack_ratio) + if not no_header: + height__ += mt.ceil(FONT_SIZE * 1.3) + width_ = width__ + height_ = height__ # our general purpose partition function def partition(tile, **args): @@ -1073,11 +1067,12 @@ def main(paths, output, *, or args.get('rectify')): partition_squarify(tile.children, tile.value, x__, y__, width__, height__, - aspect_ratio=(args['squarify_ratio'], 1) - if args.get('squarify_ratio') - else (width_, height_) - if args.get('rectify') - else (1, 1)) + aspect_ratio=( + args['squarify_ratio'] + if args.get('squarify_ratio') + else width_/height_ + if args.get('rectify') + else 1/1)) else: # default to binary partitioning partition_binary(tile.children, tile.value, @@ -2278,8 +2273,8 @@ if __name__ == "__main__": type=lambda x: ( (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) if ':' in x else float(x)), - help="Specify an explicit ratio for the squarify algorithm. " - "Implies --squarify.") + help="Specify an explicit aspect ratio for the squarify " + "algorithm. Implies --squarify.") parser.add_argument( '--to-scale', nargs='?', @@ -2290,10 +2285,10 @@ if __name__ == "__main__": help="Scale the resulting treemap such that 1 pixel ~= 1/scale " "units. Defaults to scale=1. ") parser.add_argument( - '-R', '--aspect-ratio', + '--to-ratio', type=lambda x: ( - tuple(float(v) for v in x.split(':', 1)) - if ':' in x else (float(x), 1)), + (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) + if ':' in x else float(x)), help="Aspect ratio to use with --to-scale. Defaults to 1:1.") parser.add_argument( '-t', '--tiny', diff --git a/scripts/dbgbmap.py b/scripts/dbgbmap.py index dd3d63b5..8f1c3e48 100755 --- a/scripts/dbgbmap.py +++ b/scripts/dbgbmap.py @@ -4350,7 +4350,7 @@ def main_(f, disk, mroots=None, *, lebesgue=False, contiguous=False, to_scale=None, - aspect_ratio=(1,1), + to_ratio=1/1, tiny=False, title=None, title_littlefs=False, @@ -4542,17 +4542,23 @@ def main_(f, disk, mroots=None, *, # scale width/height if requested if (to_scale is not None and (width is None or height is None)): + # don't include header in scale + width__ = width_ + height__ = height_ - (1 if not no_header else 0) + # scale width only if height is not None: - width_ = mt.ceil((len(bmap) * to_scale) / height_) + width__ = mt.ceil((len(bmap) * to_scale) / max(height__, 1)) # scale height only elif width is not None: - height_ = mt.ceil((len(bmap) * to_scale) / width_) + height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1)) # scale based on aspect-ratio else: - width_ = mt.ceil(mt.sqrt(len(bmap) * to_scale) - * (aspect_ratio[0] / aspect_ratio[1])) - height_ = mt.ceil((len(bmap) * to_scale) / width_) + width__ = mt.ceil(mt.sqrt(len(bmap) * to_scale * to_ratio)) + height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1)) + + width_ = width__ + height_ = height__ + (1 if not no_header else 0) # create a canvas canvas = Canvas( @@ -5048,13 +5054,13 @@ if __name__ == "__main__": (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) if ':' in x else float(x)), const=1, - help="Scale the resulting map such that 1 pixel ~= 1/scale " + help="Scale the resulting map such that 1 char ~= 1/scale " "blocks. Defaults to scale=1. ") parser.add_argument( - '-R', '--aspect-ratio', + '--to-ratio', type=lambda x: ( - tuple(float(v) for v in x.split(':', 1)) - if ':' in x else (float(x), 1)), + (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) + if ':' in x else float(x)), help="Aspect ratio to use with --to-scale. Defaults to 1:1.") parser.add_argument( '-t', '--tiny', diff --git a/scripts/dbgbmapd3.py b/scripts/dbgbmapd3.py index 5c74b6ec..795fd3b6 100755 --- a/scripts/dbgbmapd3.py +++ b/scripts/dbgbmapd3.py @@ -4666,7 +4666,7 @@ def main(disk, output, mroots=None, *, mode_references=False, mode_redund=False, to_scale=None, - aspect_ratio=(1,1), + to_ratio=1/1, tiny=False, title=None, title_littlefs=False, @@ -4872,17 +4872,27 @@ def main(disk, output, mroots=None, *, # scale width/height if requested if (to_scale is not None and (width is None or height is None)): + # don't include header in scale + width__ = width_ + height__ = height_ + if not no_header: + height__ -= mt.ceil(FONT_SIZE * 1.3) + # scale width only if height is not None: - width_ = mt.ceil((len(bmap) * to_scale) / height_) + width__ = mt.ceil((len(bmap) * to_scale) / max(height__, 1)) # scale height only elif width is not None: - height_ = mt.ceil((len(bmap) * to_scale) / width_) + height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1)) # scale based on aspect-ratio else: - width_ = mt.ceil(mt.sqrt(len(bmap) * to_scale) - * (aspect_ratio[0] / aspect_ratio[1])) - height_ = mt.ceil((len(bmap) * to_scale) / width_) + width__ = mt.ceil(mt.sqrt(len(bmap) * to_scale * to_ratio)) + height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1)) + + if not no_header: + height__ += mt.ceil(FONT_SIZE * 1.3) + width_ = width__ + height_ = height__ # create space for header x__ = 0 @@ -5953,10 +5963,10 @@ if __name__ == "__main__": help="Scale the resulting treemap such that 1 pixel ~= 1/scale " "blocks. Defaults to scale=1. ") parser.add_argument( - '-R', '--aspect-ratio', + '--to-ratio', type=lambda x: ( - tuple(float(v) for v in x.split(':', 1)) - if ':' in x else (float(x), 1)), + (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) + if ':' in x else float(x)), help="Aspect ratio to use with --to-scale. Defaults to 1:1.") parser.add_argument( '-t', '--tiny', diff --git a/scripts/tracebd.py b/scripts/tracebd.py index 700ae743..c01388fb 100755 --- a/scripts/tracebd.py +++ b/scripts/tracebd.py @@ -1413,7 +1413,7 @@ def main(path='-', *, lebesgue=False, contiguous=False, to_scale=None, - aspect_ratio=(1,1), + to_ratio=1/1, tiny=False, title=None, padding=0, @@ -1748,17 +1748,23 @@ def main(path='-', *, # scale width/height if requested if (to_scale is not None and (width is None or height is None)): + # don't include header in scale + width__ = width_ + height__ = height_ - (1 if not no_header else 0) + # scale width only if height is not None: - width_ = mt.ceil((len(bmap) * to_scale) / height_) + width__ = mt.ceil((len(bmap) * to_scale) / max(height__, 1)) # scale height only elif width is not None: - height_ = mt.ceil((len(bmap) * to_scale) / width_) + height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1)) # scale based on aspect-ratio else: - width_ = mt.ceil(mt.sqrt(len(bmap) * to_scale) - * (aspect_ratio[0] / aspect_ratio[1])) - height_ = mt.ceil((len(bmap) * to_scale) / width_) + width__ = mt.ceil(mt.sqrt(len(bmap) * to_scale * to_ratio)) + height__ = mt.ceil((len(bmap) * to_scale) / max(width__, 1)) + + width_ = width__ + height_ = height__ + (1 if not no_header else 0) # create a canvas canvas = Canvas( @@ -2749,13 +2755,13 @@ if __name__ == "__main__": (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) if ':' in x else float(x)), const=1, - help="Scale the resulting map such that 1 pixel ~= 1/scale " + help="Scale the resulting map such that 1 char ~= 1/scale " "blocks. Defaults to scale=1. ") parser.add_argument( - '-R', '--aspect-ratio', + '--to-ratio', type=lambda x: ( - tuple(float(v) for v in x.split(':', 1)) - if ':' in x else (float(x), 1)), + (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) + if ':' in x else float(x)), help="Aspect ratio to use with --to-scale. Defaults to 1:1.") parser.add_argument( '-t', '--tiny', diff --git a/scripts/treemap.py b/scripts/treemap.py index 054dc1aa..6348ffed 100755 --- a/scripts/treemap.py +++ b/scripts/treemap.py @@ -850,7 +850,7 @@ def partition_dice(children, total, x, y, width, height): y_ += t.height def partition_squarify(children, total, x, y, width, height, *, - aspect_ratio=(1,1)): + aspect_ratio=1/1): # this algorithm is described here: # https://www.win.tue.nl/~vanwijk/stm.pdf i = 0 @@ -861,8 +861,7 @@ def partition_squarify(children, total, x, y, width, height, *, height_ = height # note we don't really care about width vs height until # actually slicing - ratio = max(aspect_ratio[0] / aspect_ratio[1], - aspect_ratio[1] / aspect_ratio[0]) + ratio = max(aspect_ratio, 1/aspect_ratio) while i < len(children): # calculate initial aspect ratio @@ -924,7 +923,7 @@ def main_(f, csv_paths, *, no_header=False, no_stats=False, to_scale=None, - aspect_ratio=(1,1), + to_ratio=1/1, tiny=False, title=None, padding=0, @@ -951,6 +950,10 @@ def main_(f, csv_paths, *, to_scale = 1 no_header = True + # no title + no_stats implies no_header + if title is None and no_stats: + no_header = True + # what chars/colors/labels to use? chars_ = [] for char in chars: @@ -973,10 +976,7 @@ def main_(f, csv_paths, *, width_ = max(0, shutil.get_terminal_size((80, 5))[0] + width) if height is None: - height_ = (2 - if not no_header - and (title is not None or not no_stats) - else 1) + height_ = 2 if not no_header else 1 elif height > 0: height_ = height else: @@ -1062,33 +1062,23 @@ def main_(f, csv_paths, *, if (to_scale and (width is None or height is None) and tile.value != 0): - # scale if needed - if braille: - xscale, yscale = 2, 4 - elif dots: - xscale, yscale = 1, 2 - else: - xscale, yscale = 1, 1 + # don't include header in scale + width__ = width_ + height__ = height_ - (1 if not no_header else 0) # scale width only if height is not None: - width_ = mt.ceil( - ((tile.value * to_scale) / (height_*yscale)) - / xscale) + width__ = mt.ceil((tile.value * to_scale) / max(height__, 1)) # scale height only elif width is not None: - height_ = mt.ceil( - ((tile.value * to_scale) / (width_*xscale)) - / yscale) + height__ = mt.ceil((tile.value * to_scale) / max(width__, 1)) # scale based on aspect-ratio else: - width_ = mt.ceil( - (mt.sqrt(tile.value * to_scale) - * (aspect_ratio[0] / aspect_ratio[1])) - / xscale) - height_ = mt.ceil( - ((tile.value * to_scale) / (width_*xscale)) - / yscale) + width__ = mt.ceil(mt.sqrt(tile.value * to_scale * to_ratio)) + height__ = mt.ceil((tile.value * to_scale) / max(width__, 1)) + + width_ = width__ + height_ = height__ + (1 if not no_header else 0) # as a special case, if height is implicit and we have nothing to # show, don't print anything @@ -1098,10 +1088,7 @@ def main_(f, csv_paths, *, # create a canvas canvas = Canvas( width_, - height_ - (1 - if not no_header - and (title is not None or not no_stats) - else 0), + height_ - (1 if not no_header else 0), color=color, dots=dots, braille=braille) @@ -1162,11 +1149,12 @@ def main_(f, csv_paths, *, or args.get('rectify')): partition_squarify(tile.children, tile.value, x__, y__, width__, height__, - aspect_ratio=(args['squarify_ratio'], 1) + aspect_ratio=( + args['squarify_ratio'] if args.get('squarify_ratio') - else (width_, height_) + else width_/height_ if args.get('rectify') - else (1, 1)) + else 1/1)) else: # default to binary partitioning partition_binary(tile.children, tile.value, @@ -1469,8 +1457,8 @@ if __name__ == "__main__": type=lambda x: ( (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) if ':' in x else float(x)), - help="Specify an explicit ratio for the squarify algorithm. " - "Implies --squarify.") + help="Specify an explicit aspect ratio for the squarify " + "algorithm. Implies --squarify.") parser.add_argument( '--to-scale', nargs='?', @@ -1478,13 +1466,13 @@ if __name__ == "__main__": (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) if ':' in x else float(x)), const=1, - help="Scale the resulting treemap such that 1 pixel ~= 1/scale " - "units. Defaults to scale=1. ") + help="Scale the resulting treemap such that 1 char ~= 1/scale " + "units. Defaults to scale=1.") parser.add_argument( - '-R', '--aspect-ratio', + '--to-ratio', type=lambda x: ( - tuple(float(v) for v in x.split(':', 1)) - if ':' in x else (float(x), 1)), + (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) + if ':' in x else float(x)), help="Aspect ratio to use with --to-scale. Defaults to 1:1.") parser.add_argument( '-t', '--tiny', diff --git a/scripts/treemapd3.py b/scripts/treemapd3.py index 47b16121..abfd475d 100755 --- a/scripts/treemapd3.py +++ b/scripts/treemapd3.py @@ -570,7 +570,7 @@ def partition_dice(children, total, x, y, width, height): y_ += t.height def partition_squarify(children, total, x, y, width, height, *, - aspect_ratio=(1,1)): + aspect_ratio=1/1): # this algorithm is described here: # https://www.win.tue.nl/~vanwijk/stm.pdf i = 0 @@ -581,8 +581,7 @@ def partition_squarify(children, total, x, y, width, height, *, height_ = height # note we don't really care about width vs height until # actually slicing - ratio = max(aspect_ratio[0] / aspect_ratio[1], - aspect_ratio[1] / aspect_ratio[0]) + ratio = max(aspect_ratio, 1/aspect_ratio) while i < len(children): # calculate initial aspect ratio @@ -641,7 +640,7 @@ def main(csv_paths, output, *, no_header=False, no_stats=False, to_scale=None, - aspect_ratio=(1,1), + to_ratio=1/1, tiny=False, nested=False, title=None, @@ -659,6 +658,10 @@ def main(csv_paths, output, *, no_header = True no_label = True + # no title + no_stats implies no_header + if title is None and no_stats: + no_header = True + # what colors/labels to use? colors_ = Attr(colors, defaults=COLORS_DARK if dark else COLORS) @@ -753,17 +756,27 @@ def main(csv_paths, output, *, if (to_scale is not None and (width is None or height is None) and tile.value != 0): + # don't include header in scale + width__ = width_ + height__ = height_ + if not no_header: + height__ -= mt.ceil(FONT_SIZE * 1.3) + # scale width only if height is not None: - width_ = mt.ceil((tile.value * to_scale) / height_) + width__ = mt.ceil((tile.value * to_scale) / max(height__, 1)) # scale height only elif width is not None: - height_ = mt.ceil((tile.value * to_scale) / width_) + height__ = mt.ceil((tile.value * to_scale) / max(width__, 1)) # scale based on aspect-ratio else: - width_ = mt.ceil(mt.sqrt(tile.value * to_scale) - * (aspect_ratio[0] / aspect_ratio[1])) - height_ = mt.ceil((tile.value * to_scale) / width_) + width__ = mt.ceil(mt.sqrt(tile.value * to_scale * to_ratio)) + height__ = mt.ceil((tile.value * to_scale) / max(width__, 1)) + + if not no_header: + height__ += mt.ceil(FONT_SIZE * 1.3) + width_ = width__ + height_ = height__ # sort tile.sort() @@ -791,7 +804,7 @@ def main(csv_paths, output, *, height__ = tile.height # create space for header - if not no_header and (title is not None or not no_stats): + if not no_header: y__ += mt.ceil(FONT_SIZE * 1.3) height__ -= min(mt.ceil(FONT_SIZE * 1.3), height__) @@ -837,11 +850,12 @@ def main(csv_paths, output, *, or args.get('rectify')): partition_squarify(tile.children, tile.value, x__, y__, width__, height__, - aspect_ratio=(args['squarify_ratio'], 1) + aspect_ratio=( + args['squarify_ratio'] if args.get('squarify_ratio') - else (width_, height_) + else width_/height_ if args.get('rectify') - else (1, 1)) + else 1/1)) else: # default to binary partitioning partition_binary(tile.children, tile.value, @@ -880,7 +894,7 @@ def main(csv_paths, output, *, background=background_)) # create header - if not no_header and (title is not None or not no_stats): + if not no_header: f.write('' % dict( color='#ffffff' if dark else '#000000')) if not no_stats: @@ -1114,8 +1128,8 @@ if __name__ == "__main__": type=lambda x: ( (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) if ':' in x else float(x)), - help="Specify an explicit ratio for the squarify algorithm. " - "Implies --squarify.") + help="Specify an explicit aspect ratio for the squarify " + "algorithm. Implies --squarify.") parser.add_argument( '--to-scale', nargs='?', @@ -1126,10 +1140,10 @@ if __name__ == "__main__": help="Scale the resulting treemap such that 1 pixel ~= 1/scale " "units. Defaults to scale=1. ") parser.add_argument( - '-R', '--aspect-ratio', + '--to-ratio', type=lambda x: ( - tuple(float(v) for v in x.split(':', 1)) - if ':' in x else (float(x), 1)), + (lambda a, b: a / b)(*(float(v) for v in x.split(':', 1))) + if ':' in x else float(x)), help="Aspect ratio to use with --to-scale. Defaults to 1:1.") parser.add_argument( '-t', '--tiny',