def title(rule): d1 = axi.Drawing(axi.text('Rule %d' % rule, axi.FUTURAM)) d1 = d1.scale_to_fit_height(0.25) d2 = axi.Drawing(axi.text('Elementary Cellular Automaton', axi.FUTURAL)) d2 = d2.scale_to_fit_height(0.1875) ds = [d1, d2] d = vertical_stack(ds, 0.125) d = d.join_paths(0.01) d = d.simplify_paths(0.001) return d
def title(): d1 = axi.Drawing(axi.text('Topography of', axi.METEOROLOGY)) d1 = d1.scale_to_fit_height(0.25) d2 = axi.Drawing(axi.text('Vancouver Island', axi.METEOROLOGY)) d2 = d2.scale_to_fit_height(0.375) d = vertical_stack([d1, d2], 0.125, False) d = d.join_paths(0.01) d = d.simplify_paths(0.001) d = d.move(0, 8.5, 0, 1) return d
def punchcard_from_csv(csv_path): with open(csv_path, 'rb') as fp: reader = csv.reader(fp) csv_rows = list(reader) row_labels = [x[0] for x in csv_rows[1:]] col_labels = csv_rows[0][1:] data = [] for csv_row in csv_rows[1:]: row = [] for value in csv_row[1:]: try: value = float(value) except ValueError: value = None row.append(value) data.append(row) lo = min(x for row in data for x in row if x) hi = max(x for row in data for x in row if x) min_area = math.pi * (MIN_SIZE / 2.0)**2 max_area = math.pi * (MAX_SIZE / 2.0)**2 paths = [] for r, row in enumerate(data): for c, value in enumerate(row): if not value: continue pct = 1.0 * (value - lo) / (hi - lo) pct = pct**0.5 area = pct * (max_area - min_area) + min_area radius = (area / math.pi)**0.5 paths.extend(fill_circle(c, r, radius, 90)) for r, label in enumerate(row_labels): d = axi.Drawing(axi.text(label.upper(), axi.TIMESR)) d = d.scale(0.02, 0.02).move(-1, r, 0.5, 0.5) paths.extend(d.paths) for c, label in enumerate(col_labels): d = axi.Drawing(axi.text(label.upper(), axi.TIMESR)) d = d.scale(0.02, 0.02).move(c, -1, 0.5, 0.5) paths.extend(d.paths) d = axi.Drawing(paths) d = d.scale_to_fit(12, 8.5) print('joining paths') d = d.join_paths(0.02) print('simplifying paths') d = d.simplify_paths(0.001) d.render().write_to_png('out.png') axi.draw(d)
def main(): paths = [] add(0, 0, 64, paths) drawing = axi.Drawing(paths) cli = axi.cli() cli.draw(drawing)
def title(): d = axi.Drawing( axi.text('Topography of the Western United States', axi.FUTURAM)) d = d.scale_to_fit_height(0.25) d = d.join_paths(0.01) d = d.simplify_paths(0.001) return d
def multiple_label(text): d = axi.Drawing(axi.text(text, axi.FUTURAL)) d = d.scale_to_fit_height(0.125) d = d.move(0, 8.5, 0, 1) d = d.join_paths(0.01) d = d.simplify_paths(0.001) return d
def render_complete(scene): if not pp.lineset: return device = connect_plotter() if not device: self.report({'ERROR'}, "Failed to connect to AxiDraw.") return drawing = axi.Drawing(pp.lineset) drawing = drawing.scale(scale_factor(scene)) if plotter.join_paths: drawing = drawing.join_paths(plotter.join_paths_threshold) if plotter.sort_paths: drawing = drawing.sort_paths() device.run_drawing(drawing, True) disconnect_plotter(device) editor.callbacks_lineset_post.remove(pp.lineset_post) editor.callbacks_modifiers_post.remove(pp.modifier_post) bpy.app.handlers.render_complete.remove(render_complete)
def main(): filename = sys.argv[1] print('loading image') im = Image.open(filename) im = im.convert('L') w, h = im.size data = list(im.getdata()) paths = [] for y in range(h): for x in range(w): if data[y * w + x] == 0: paths.append([(x, y), (x, y)]) random.shuffle(paths) print(len(paths)) d = axi.Drawing(paths) print('transforming paths') # d = d.scale(1, -1) d = d.rotate_and_scale_to_fit(12, 8.5, step=90) # print 'sorting paths' # d = d.sort_paths() # print 'joining paths' # d = d.join_paths(0.05) # print len(d.paths) print('sorting paths') d = d.sort_paths() print('joining paths') d = d.join_paths(0.03) print(len(d.paths)) d.paths = [x for x in d.paths if len(x) > 2] print('simplifying paths') d = d.simplify_paths(0.002) print(len(d.paths)) print('rendering paths') d.render(line_width=0.3 / 25.4).write_to_png('out.png') axi.draw(d)
def main(): # random.seed(1182) points, pairs = poisson_disc(0, 0, 11, 8.5, 0.035, 32) path = make_path(pairs) drawing = axi.Drawing([path]).scale_to_fit(11, 8.5) drawing.render().write_to_png('out.png') axi.draw(drawing)
def main(): dirname = 'overlapping_circles' i = 0 j = 0 x = 0 y = 0 drawing = axi.Drawing([]) for filename in sorted(os.listdir(dirname)): if not filename.endswith('.axi'): continue path = os.path.join(dirname, filename) print(path) d = load(path) d = d.translate(x, y) drawing.add(d) x += SPACING i += 1 if i == N_PER_ROW: i = 0 j += 1 x = 0 if j % 2: x = SPACING / 2 y += SPACING * 0.866 d = drawing d = d.center(*axi.A3_SIZE) print(len(d.paths)) im = d.render(bounds=axi.A3_BOUNDS, line_width = 0.4 / 25.4) im.write_to_png('overlapping_circles.png') d.dump('overlapping_circles.axi')
def drawing_end(raw=False): global paths global title d = axi.Drawing(paths) text_pos = (PADDING, V3_SIZEX-PADDING) if not raw: if cfg.y_up: d = d.scale(1.0, -1.0) d = d.scale_to_fit(CELLSIZEX, CELLSIZEY, PADDING) d = d.translate(POSX*CELLSIZEX, POSY*CELLSIZEY) text_pos = (POSX*CELLSIZEX, (POSY+1)*CELLSIZEY-PADDING) nextpos() if title: font = axi.Font(axi.FUTURAL, 7.5) # dtext = font.text(title) dtext dtext = dtext.translate(*text_pos) d.add(dtext) axi.draw(d) title = '' # Reset title print("DRAWING END") print("")
def label(): d = axi.Drawing(axi.text(LABEL, axi.FUTURAL)) d = d.scale_to_fit_height(0.125) d = d.rotate(-90) d = d.move(12, 8.5, 1, 1) d = d.join_paths(0.01) return d
def draw(self): if self.paths: if self.params['sort paths']: paths = axi.sort_paths(self.paths) else: paths = self.paths self.device.run_drawing(axi.Drawing(paths), True)
def stack_drawings(ds, spacing=0): result = axi.Drawing() y = 0 for d in ds: d = d.origin().translate(-d.width / 2, y) result.add(d) y += d.height + spacing return result
def main(): paths = [ [(0, 0), (W, 0), (W, H), (0, H), (0, 0)] ] d = axi.Drawing(paths) d = d.center(*BOUNDS[-2:]) d.dump('box.axi') d.render(bounds=BOUNDS).write_to_png('box.png')
def abstract(): ds = [axi.Drawing(p) for p in axi.justify_text(ABSTRACT, axi.TIMESR)] spacing = max(d.height for d in ds) * 1.5 ds = [d.translate(0, i * spacing) for i, d in enumerate(ds)] d = concat(ds) d = d.scale_to_fit_width(8.5) d = d.join_paths(0.01) return d
def main(): W = 8.5 H = 0.5 total = sum(x[1] for x in DATA) lo = min(x[0] for x in DATA) hi = max(x[0] for x in DATA) peak = max(x[1] for x in DATA) paths = [] path = [] for key, count in DATA: x = W * (key - lo) / (hi - lo) y = H * count / peak path.append((x, -y)) if y > 0.01: paths.append([(x, 0), (x, -y)]) paths.append(path) paths.append([(0, 0), (W, 0)]) labels = [0, 1000, 2000, 3000, 3851] for key in labels: x = W * (key - lo) / (hi - lo) paths.append([(x, 0.0), (x, 0.05)]) d = axi.Drawing(axi.text(str(key), axi.FUTURAL)) d = d.scale_to_fit_height(0.1) d = d.move(x, 0.15, 0.5, 0) paths.extend(d.paths) title = 'Elevation Distribution (meters above sea level)' d = axi.Drawing(axi.text(title, axi.FUTURAL)) d = d.scale_to_fit_height(0.15) d = d.move(W / 2, 0.3, 0.5, 0) paths.extend(d.paths) d = axi.Drawing(paths) d = d.rotate(180) d = d.rotate_and_scale_to_fit(8.5, 8.5, step=90) d = d.move(12, 8.5 / 2, 1, 0.5) print d.bounds d = d.sort_paths() d = d.join_paths(0.01) d = d.simplify_paths(0.001) d.render().write_to_png('out.png') d.dump('out.axi')
def horizontal_stack(ds, spacing=0): result = axi.Drawing() x = 0 for d in ds: d = d.origin().translate(x, -d.height / 2) result.add(d) x += d.width + spacing return result
def title(): ds = [axi.Drawing(axi.text(line, axi.TIMESIB)) for line in TITLE] spacing = max(d.height for d in ds) * 1.5 ds = [d.translate(-d.width / 2, i * spacing) for i, d in enumerate(ds)] d = concat(ds) d = d.scale_to_fit_width(8.5) d = d.join_paths(0.01) return d
def polygon(n, r, br, notch=False): p = regular_polygon(n, 0, 0, r) g = geometry.Polygon(p) g = g.buffer(br).exterior if notch: g = g.difference(polygon_splits(n, 0, 0, r * 2, br * 2)) g = ops.linemerge(g) p = axi.shapely_to_paths(g) return axi.Drawing(p).origin()
def justify_text(self, text, width): d = self.text(text) w = d.width spaces = text.count(' ') if spaces == 0 or w >= width: return d e = ((width - w) / spaces) / self.scale d = axi.Drawing(axi.text(text, self.font, extra=e)) d = d.scale(self.scale) return d
def main(): layer = make_layer() layer.save('layer.png', 0, 0, W, H, 50) points, pairs = poisson_disc(layer, 0, 0, W, H, 0.05, 8) path = make_path(pairs) d = axi.Drawing([path]) # d = d.rotate_and_scale_to_fit(W, H, step=90) d = d.scale_to_fit(W, H) d.dump('growth.axi') d.render(bounds=(0, 0, W, H)).write_to_png('growth.png')
def lng_label(text, x): d = axi.Drawing(axi.text(text, axi.FUTURAL)) d = d.scale_to_fit_height(0.1) d = d.move(x, HEIGHT + 0.125, 0.5, 1) # d.paths.append(circle(x + d.width / 2 + 1 / 16, 8.5 + 0.125 - d.height, 1 / 48, 36)) d = d.join_paths(0.01) d = d.simplify_paths(0.001) paths = d.paths paths.append([(x, HEIGHT - 1 / 8), (x, HEIGHT - 1 / 16)]) return paths
def lat_label(text, y): d = axi.Drawing(axi.text(text, axi.FUTURAL)) d = d.scale_to_fit_height(0.1) d = d.move(WIDTH + 1 / 8, y, 0, 1) # d.paths.append(circle(12.125 + d.width + 1 / 16, y - d.height, 1 / 48, 36)) d = d.join_paths(0.01) d = d.simplify_paths(0.001) paths = d.paths # paths.append([(WIDTH, y), (WIDTH + 1 / 16, y)]) return paths
def main(): text = stack_drawings([title(), subtitle()], 0.3125) text = text.rotate(-90) text = text.move(12, 8.5 / 2, 1, 0.5) # text = title() filenames = [ sys.argv[1], # 'ribbon/1j1c.txt', # 'ribbon/amyloid-beta/1mwp.txt', # 'ribbon/amyloid-beta/1owt.txt', # 'ribbon/amyloid-beta/1rw6.txt', # 'ribbon/amyloid-beta/1iyt.txt', ] angles = [90, 90, 75, 60] print('loading paths') ds = [] for filename, angle in zip(filenames, angles): ds.append(axi.Drawing(axi.load_paths(filename)).scale(1, -1)) # d = grid_drawings(ds, 2, 1) d = ds[0] print(len(d.paths)) print('joining paths') d = d.join_paths(0.01) print(len(d.paths)) print('transforming paths') # d = d.scale(1, -1) d = d.rotate(180) d = d.rotate_and_scale_to_fit(8.5, 12 - text.height) # d = d.origin() print('sorting paths') d = d.sort_paths() print('joining paths') d = d.join_paths(0.01) print(len(d.paths)) print('simplifying paths') d = d.simplify_paths(0.001) # add title and label and fit to page # d = stack_drawings([d, text], 1) # d = d.rotate(-90) # d = d.center(12, 8.5) d = d.rotate_and_scale_to_fit(12, 8.5).translate(-text.width * 0.6666, 0) d.add(text) # d.add(title()) d.add(label()) print('rendering paths') d.render(line_width=0.25 / 25.4).write_to_png('out.png') # axi.draw(d) print(d.bounds) d.dump('out.axi') d.dump_svg('out.svg')
def vertical_stack(ds, spacing=0, center=True): result = axi.Drawing() y = 0 for d in ds: x = 0 if center: x = -d.width / 2 d = d.origin().translate(x, y) result.add(d) y += d.height + spacing return result
def circles(): x = 0 r = 0 paths = [] while x + r < W: paths.append(circle(x, 0, r, 2, 360)) x += r r += 0.0025 x += r x += 0.1 return axi.Drawing(paths)
def main(): paths = [] with open('./output/composed.geojson') as fp: for line in fp: js = json.loads(line) for p in axi.shapely_to_paths(shape(js["geometry"])): paths.append(p) d = axi.Drawing(paths) d = d.scale_to_fit(11.69, 8.5, padding=0) d = d.sort_paths() d.dump_svg('./output/out.svg')
def main(): paths = [] im = Image.open(sys.argv[1]) im = im.convert('L') im = crop(im) # im.save('crop.png') print im.size w, h = im.size data = np.asarray(im) data = data / np.amax(data) # data = data ** 0.5 lines_per_row = int(h / ROWS) for j in range(0, ROWS, 1): y0 = j * lines_per_row y1 = y0 + lines_per_row d = data[y0:y1] for q in range(0, 101, 25): print j, q values = np.percentile(d, q, axis=0) * 1.2 path = enumerate(values) for path in remove_flats(path): x = np.array([p[0] for p in path]) * WIDTH / w y = (j - np.array([p[1] for p in path])) * HEIGHT / ROWS path = zip(x, y) path = axi.simplify_paths([path], 0.005)[0] paths.append(path) lat = LAT1 + (LAT2 - LAT1) * j / (ROWS) paths.extend(lat_label('%g' % lat, j * HEIGHT / ROWS)) for lng in range(LNG1, LNG2 + 1): x = (lng - LNG1) / (LNG2 - LNG1) * WIDTH paths.extend(lng_label('%g' % abs(lng), x)) d = axi.Drawing(paths) print len(d.paths) print 'joining paths' d = d.join_paths(0.01) print len(d.paths) print 'sorting paths' d = d.sort_paths() print 'joining paths' d = d.join_paths(0.01) print len(d.paths) d = vertical_stack([title(), d], 0.25) # d = d.rotate(180) d = d.rotate_and_scale_to_fit(12, 8.5, step=90) im = d.render( scale=109 * 1, line_width=0.3 / 25.4, ) #show_axi_bounds=False, use_axi_bounds=False) im.write_to_png('out.png') # d = d.rotate_and_scale_to_fit(12, 8.5, step=90) d.dump('out.axi')
def multiple(): w = 32 h = 137 # rules = [x for x in range(256) if bin(x).count('1') == 4] # rules = [18, 22, 26, 30, 41, 45, 54, 60, 73, 90, 105, 106, 110, 122, 126, 146, 150, 154] # rules = sorted(random.sample(rules, 6)) # print rules # rules = sorted([22, 30, 60, 90, 106, 150, 105, 122, 154]) rules = sorted([22, 30, 60, 90, 106, 150]) ds = [] for rule in rules: d1 = create_drawing(rule, w, h) d1 = d1.scale_to_fit_height(8) d2 = axi.Drawing(axi.text('Rule %d' % rule, axi.FUTURAL)) d2 = d2.scale_to_fit_height(0.125) d = vertical_stack([d1, d2], 0.125) ds.append(d) title = axi.Drawing(axi.text('Elementary Cellular Automata', axi.FUTURAM)) title = title.scale_to_fit_height(0.25) d = horizontal_stack(ds, 0.25) d = vertical_stack([title, d], 0.2) d = d.scale_to_fit(12, 8.5) # d.add(multiple_label('#31')) print len(d.paths) print 'joining paths' d = d.join_paths(0.01) print len(d.paths) print 'sorting paths' d = d.sort_paths() print len(d.paths) print 'joining paths' d = d.join_paths(0.01) print len(d.paths) print 'simplifying paths' d = d.simplify_paths(0.001) print d.bounds d.dump('out.axi') im = d.render(scale=109 * 1, line_width=0.3 / 25.4, show_axi_bounds=False) im.write_to_png('out.png')