def main(): parser = ArgumentParser() parser.add_argument('--group', choices=['first', 'second', 'everything'], default='everything') parser.add_argument('--area') parser.add_argument('-t', '--type', choices=['first', 'second']) add_date_arg(parser, help='first release to use', default=earliest_vaccination) add_date_arg(parser, '--to-date', default=find_latest('vaccination_cum_*')[1]) parser.add_argument('--duration', type=float, default=0.2) parser.add_argument('--raise-errors', action='store_true') args = parser.parse_args() if args.type: to_show = tuple_product_array( [' '.join(w.capitalize() for w in args.area.split('-'))], args.type.capitalize()) name = f'{args.area}_{args.type}' else: to_show = selection_mapping(args.from_date)[args.group] name = args.group dates = pd.date_range(args.from_date, args.to_date) parallel_render(f'animated_vaccinations_{name}', partial(render_plots, to_show, args.to_date), dates, duration=args.duration, raise_errors=args.raise_errors)
def main(): parser = ArgumentParser() add_date_arg(parser, help='first release to use', default=earliest_testing) add_parallel_args(parser, default_duration=0.1, default_output='gif', from_date=False) parser.add_argument('config', choices=BARS.keys()) add_date_arg(parser, '--earliest', help='min for x-axis', default=second_wave) parser.add_argument('--diff-log-scale', action='store_true') parser.add_argument('--diff-no-lims', action='store_true') parser.add_argument('--ylim', type=float) parser.add_argument('--y-max-factor', type=float, default=1.02) args = parser.parse_args() config = Bars.get(args.config, earliest=args.earliest) from_date = max(args.from_date, args.earliest) dates = available_dates(config.metric, config.data_file_stem, earliest=from_date) to_date = parallel_to_date(args, dates[0]) if to_date != dates[0]: dates = [d for d in dates if d <= to_date] latest_date = dates[0] max_metric = config.data_for(latest_date)[0].sum( axis=1).max() * args.y_max_factor params = {} if args.diff_no_lims: params['diff_ylims'] = None lines = config.lines_for(latest_date) if lines: params['line_ylim'] = max(l.data.max() for l in lines) * args.y_max_factor parallel_render( f'animated_{args.config}', partial(plot_bars, config=config, ylim=args.ylim or max_metric, diff_log_scale=args.diff_log_scale, show_title=True, to_date=date.today(), **params), dates, **parallel_params(args, item_is_timestamp=False))
def main(): parser = ArgumentParser() group = parser.add_mutually_exclusive_group() add_date_arg(group, '--start', default=earliest_msoa) group.add_argument('--composite', action='store_true') args = parser.parse_args() checkers = [] min_date = str(date.max) max_date = str(date.min) if args.composite: files = [(None, base_path / 'msoa_composite.csv')] else: files = msoa_files(args.start) for path_dt, path in files: checker = Checker(path_dt, path) checkers.append(checker) for row in DictReader(lines_from(path)): checker.add_row(row) row_date = row[date_col] min_date = min(min_date, row_date) max_date = max(max_date, row_date) for dt in pd.date_range(min_date, max_date): d = str(dt.date()) files = [i.name for i in reversed(checkers) if d in i.rows_per_date] if args.composite: if not files: print(f"{d}: missing") else: print(f"{d}: {', '.join(files)}") print() for checker in checkers: try: checker.check() except AssertionError as e: print(f'{checker.name}: {e}') print() out_of_date = (date.today() - pd.to_datetime(max_date).date()).days - Checker.expected_gap print(f'latest date seen: {max_date} ({out_of_date} days out of date)')
def main(args=None): parser = ArgumentParser() add_date_arg(parser, '--start') parser.add_argument('--clean', action='store_true') parser.add_argument('--output', default=base_path / 'msoa_composite.csv', type=Path) parser.add_argument('--no-check', dest='check', action='store_false') args = parser.parse_args(args) fieldnames = None rows = {} if args.output.exists() and not args.clean: add_from(args.output, rows, check=False) start = args.start if start is None: if rows: max_date = max(key_[0] for key_ in rows) start = (pd.to_datetime(max_date) + pd.Timedelta(Checker.expected_gap + 1, 'D')).date() else: start = date(2020, 12, 1) for dt, path in msoa_files(start): fieldnames = add_from(path, rows, dt, args.check, modifier=add_blank_rows) if fieldnames is None or not rows: return with open(args.output, 'w') as target: writer = DictWriter(target, fieldnames + [release_timestamp]) writer.writeheader() for _, row in tqdm(sorted(rows.items()), desc='writing'): writer.writerow(row)
def main(): parser = ArgumentParser() parser.add_argument('sets', choices=list(SETS), nargs='+') parser.add_argument('--name') add_date_arg(parser, '--start') add_date_arg(parser, '--end') add_date_arg(parser, '--date', default=date.today()) parser.add_argument('--debug', action='store_true') parser.add_argument('--overwrite', action='store_true') args = parser.parse_args() if args.debug: logging.basicConfig(level=logging.DEBUG) if args.start and args.end: points = args.start, args.end dates = [dt.date() for dt in pd.date_range(min(*points), max(*points))] else: dates = [args.date] release_timestamp = get_release_timestamp() expected = 0 downloaded = 0 for dt in reversed(dates): if pd.to_datetime(dt, utc=True) > release_timestamp: print(f'{dt} not yet available, current: {release_timestamp}') continue for dl in chain(*(SETS[s] for s in args.sets)): name = dl.name or dl.area_name or dl.area_type if args.name and name != args.name: continue expected += 1 data_path = (base_path / f'{name}_{dt}.csv') if data_path.exists() and not args.overwrite: print('already exists:', data_path) downloaded += 1 continue try: data_path = retrying_phe_download(name, dl.area_type, *dl.metrics, area_name=dl.area_name, release=dt) except NoContent: print(f'no content for {name} on {dt}') else: print('downloaded: ', data_path) downloaded += 1 if downloaded != expected: print(f'expected {expected}, but {downloaded} downloaded') return 1 return 0
def main(): parser = ArgumentParser() parser.add_argument('name') parser.add_argument('--threads', type=int, default=cpu_count()) parser.add_argument('--build', action='store_true') parser.add_argument('--duration', type=float, default=0.06, help='fast=0.05, slow=0.3') parser.add_argument('--final-duration', type=float, default=3) # overrides add_date_arg(parser, '--start') add_date_arg(parser, '--end') parser.add_argument('--dpi', type=int) parser.add_argument('--output', choices=['mp4', 'gif'], default='mp4') args = parser.parse_args() composition = compositions[args.name] overrides = {} for arg in 'start', 'end', 'dpi': value = getattr(args, arg) if value: overrides[arg] = value composition.override(overrides) if args.build: for part in composition.parts: part.build() part_to_frames = composition.organise() frame_counts = set(len(frames) for frames in part_to_frames.values()) assert len(frame_counts) == 1, repr(frame_counts) length, = frame_counts if composition.durations: durations = composition.durations(length) else: durations = [args.duration] * length if args.final_duration: durations[-1] = args.final_duration def frames_and_durations_for(p): return {f: d for (f, d) in zip(part_to_frames[p], durations)} final = clips_array([[ clips_array([[p.clip(frames_and_durations_for(p)) for p in row]], bg_color=white) ] for row in composition.rows], bg_color=white) final = final.set_duration(sum(durations)) # 4k = 3840 # 1080p = 1920 path = str(output_path / f"{args.name}.{args.output}") if args.output == 'mp4': final.write_videofile(path, fps=24, threads=args.threads, bitrate='10M') else: final.write_gif(path, fps=24) print('shrinking...') optimize(path)