def main(): print("command line:\n{}\n".format(' '.join(sys.argv))) args = parse_args() dpi = args.dpi image_resolution = args.resolution figure_dimensions = [ float(image_resolution[0]) / dpi, float(image_resolution[1]) / dpi ] print("STATUS: Initializing canvas") figure = pyplot.figure(figsize=figure_dimensions) axes = figure.add_axes([0, 0, 1, 1], frameon=False) axes.set_frame_on(False) print("STATUS: Initializing trajectory source") trajectory_source = setup_trajectory_source(args.trajectory_data_file[0], args) # This is a little bit ugly but I don't yet know of a better way # to do it. If we want to automatically compute the bounding box # of the data points before we render anything we must read all the # points at least once. # # That gives us a choice: read them once and keep them all in # memory, or make one pass through the file to compute the # bounding box and then another to read and render the points? # # For the moment I elect to read the points and keep them in memory. if args.domain == 'cartesian2d' and args.map_bbox is None: print("STATUS: Collecting points to compute bounding box") all_trajectories = itertools.chain(list(trajectory_source)) data_bbox = geomath.compute_bounding_box(all_points) point_source = all_points args.map_bbox = data_bbox print("STATUS: Creating map projection") mapmaker_args = argument_groups.extract_arguments("mapmaker", args) (mymap, map_actors) = mapmaker.mapmaker(**mapmaker_args) print("STATUS: Reading trajectories and rendering data") color_scale = matplotlib.colors.Normalize(vmin=0, vmax=1) render_trajectories(mymap, trajectory_source, args) print("STATUS: Saving figure to file") pyplot.savefig( args.image_file[0], # facecolor=figure.get_facecolor(), facecolor='white', figsize=figure_dimensions, dpi=dpi, frameon=False) pyplot.close() return 0
def encode_final_movie(output_filename, tmpdir, args): """Re-encode the finished movie to user specifications. We generate the movie originally using a lossless encoding. This results in a very large file. Typically the user will want it in a different format that's easier to move around. This function does that with a call to ffmpeg. Args: output_filename (string): User-specified filename for the finished movie tmpdir (string): Path to work directory args (argparse.Namespace): All arguments parsed from command line Side Effects: Movie will be transcoded from its intermediate format and written to the output file. """ movie_kwargs = argument_groups.extract_arguments('movie_rendering', args) if movie_kwargs.get('encoder_args', None) is not None: encoder_args = shlex.split(movie_kwargs['encoder_args']) else: encoder_args = [ "-c", "copy" ] # print("DEBUG: encode_final_movie: Extra encoder args are {}".format(encoder_args)) # Now we re-encode the assembled movie to whatever specs the user wanted ffmpeg_args = [ 'ffmpeg', '-i', os.path.join(tmpdir, 'assembled.mkv') ] ffmpeg_args += encoder_args ffmpeg_args += [ os.path.abspath(output_filename) ] # print("DEBUG: ffmpeg args for final encode: {}".format(ffmpeg_args)) subprocess.check_call(ffmpeg_args)
def configure_trajectory_reader(infile, **kwargs): """Set up a TrajectoryReader. Args: infile: An open file or file-like object containing the input. Returns: The ready-to-use trajectory reader. In order to actually retrieve the trajectories, iterate over the contents of the object returned by this function. """ reader_args = extract_arguments('trajectory_reader', kwargs) domain = reader_args['domain'] if domain.lower() not in ALL_DOMAINS: raise KeyError( "Domain '{}' is not in list of installed domains ({}).".format( domain, ', '.join(ALL_DOMAINS))) else: domain_to_import = 'tracktable.domain.{}'.format(domain.lower()) domain_module = importlib.import_module(domain_to_import) reader = domain_module.TrajectoryReader() reader.input = infile return reader
def render_trajectories(basemap, trajectory_source, args): render_args = argument_groups.extract_arguments("trajectory_rendering", args) example_trajectory_rendering.render_trajectories(basemap, trajectory_source, **render_args)
def setup_trajectory_source(point_source, args): args = argument_groups.extract_arguments("trajectory_assembly", args) source = example_trajectory_builder.configure_trajectory_builder(**args) source.input = point_source return source.trajectories()
def setup_trajectory_source(point_source, args): args = argument_groups.extract_arguments("trajectory_assembly", args) source = example_trajectory_builder.configure_trajectory_builder(**args) print("DEBUG: Trajectory source in setup_trajectory_source is a {}".format(type(source))) source.input = point_source return source.trajectories()
def setup_chunk_renderer(args): """Instantiate and configure the render manager This function sets up a MovieChunkRenderer so that it's all ready to start processing batches of frames. This includes setting up Matplotlib and Basemap, loading trajectory data from disk and storing information in the renderer that does not change between frames. Args: args (argparse.Namespace): All arguments parsed from command line Side Effects: The renderer is stored in the global variable CHUNK_RENDERER. Known Bugs: Global variables are not thread-safe. """ renderer = MovieChunkRenderer() global CHUNK_RENDERER CHUNK_RENDERER = renderer renderer.all_args = args setup_matplotlib_figure(args, CHUNK_RENDERER) setup_basemap(args, CHUNK_RENDERER) all_trajectories = collect_trajectories(args) renderer.trajectories = all_trajectories movie_kwargs = argument_groups.extract_arguments("movie_rendering", args) trajectory_kwargs = argument_groups.extract_arguments("trajectory_rendering", args) renderer.trajectory_rendering_kwargs = trajectory_kwargs renderer.movie_kwargs = movie_kwargs renderer.trail_duration = datetime.timedelta(seconds=args.trail_duration) renderer.start_time = args.start_time renderer.end_time = args.end_time renderer.fps = args.fps renderer.num_frames_overall = renderer.fps * args.duration if renderer.utc_offset: renderer.utc_offset = int(args.utc_offset) if args.timezone_label: renderer.timezone_label = args.timezone_label
def main(): args = parse_args() dpi = args.dpi image_resolution = args.resolution figure_dimensions = [ float(image_resolution[0]) / dpi, float(image_resolution[1]) / dpi ] print("STATUS: Initializing image") figure = pyplot.figure(figsize=figure_dimensions, facecolor='black', edgecolor='black') axes = figure.add_axes([0, 0, 1, 1], frameon=False, facecolor='black') axes.set_frame_on(False) print("STATUS: Creating geographic map") mapmaker_kwargs = argument_groups.extract_arguments("mapmaker", args) if args.domain == 'terrestrial': (mymap, artists) = mapmaker.terrestrial_map(axes=axes, **mapmaker_kwargs) elif args.domain == 'cartesian2d': if len(mapmaker_kwargs.map_bbox) == 0: bbox = 'auto' else: bbox = BoundingBox2D( Point2D(mapmaker_kwargs.bbox[0], mapmaker_kwargs.bbox[1]), Point2D(mapmaker_kwargs.bbox[2], mapmaker_kwargs.bbox[3])) (mymap, artists) = mapmaker.cartesian_map(axes=axes, map_bbox=bbox) else: raise AttributeError( 'Domain {} does not yet have render support.'.format(args.domain)) print("STATUS: Initializing point source") source = setup_point_source(args.point_data_file[0], args) all_points = [point for point in source] print("STATUS: Reading points and rendering histogram") render_histogram(mymap, args.domain, all_points, args.histogram_bin_size, args.colormap, args.scale) print("STATUS: Saving figure to file") pyplot.savefig(args.image_file[0], figsize=figure_dimensions, dpi=dpi, frameon=False) pyplot.close() return 0
def setup_basemap(args, renderer): """Call Mapmaker to set up our map projection. Args: args (argparse.Namespace): Arguments parsed from command line renderer (MovieChunkRenderer): Render manager Side Effects: A pointer to the Basemap instance will be saved in the renderer. Known Bugs: The list of artists that are added to the map as decorations is being ignored. """ mapmaker_kwargs = argument_groups.extract_arguments("mapmaker", args) (mymap, base_artists) = mapmaker.terrestrial_map(**mapmaker_kwargs) renderer.basemap = mymap
def setup_trajectory_source(point_source, args): """Set up pipeline to assemble points into trajectories Before you call this function you must have an iterable of TrajectoryPoint objects. We will configure an AssembleTrajectoriesFromPoints source and return a generator for its results. its results. Args: point_source (iterable): Sequence of TrajectoryPoint objects args (argparse.Namespace): Arguments parsed from command line Yields: Trajectory objects """ args = argument_groups.extract_arguments("trajectory_assembly", args) source = example_trajectory_builder.configure_trajectory_builder(**args) source.input = point_source return source.trajectories()
def main(): args = parse_args() dpi = args.dpi image_resolution = args.resolution if image_resolution is None: image_resolution = [ 800, 600 ] figure_dimensions = [ float(image_resolution[0]) / dpi, float(image_resolution[1]) / dpi ] print("STATUS: Initializing image") figure = pyplot.figure(figsize=figure_dimensions, facecolor='black', edgecolor='black') axes = figure.add_axes([0, 0, 1, 1], frameon=False, axisbg='black') axes.set_frame_on(False) mapmaker_kwargs = argument_groups.extract_arguments("mapmaker", args) (mymap, base_artists) = mapmaker.mapmaker(**mapmaker_kwargs) print("STATUS: Initializing point source for main data file") main_point_source = setup_point_source(args.point_data_file[0], args) print("STATUS: Initializing trajectory source for main data file") main_trajectory_source = setup_trajectory_source(main_point_source, args) print("STATUS: Collecting all trajectories from main source") all_trajectories = list(main_trajectory_source) highlight_trajectories = [] if len(args.highlight) > 0: print("STATUS: Initializing point source for highlight data file") highlight_point_source = setup_point_source(args.highlight[0], args) print("STATUS: Initializing trajectory source for highlight data file") highlight_trajectory_source = setup_trajectory_source(highlight_point_source, args) print("STATUS: Collecting trajectories to highlight") highlight_trajectories = list(highlight_trajectory_source) movie_kwargs = argument_groups.extract_arguments("movie_rendering", args) movie_writer = example_movie_rendering.setup_encoder(**movie_kwargs) # This set of arguments will be passed to the savefig() call that # grabs the latest movie frame. This is the place to put things # like background color, tight layout and friends. savefig_kwargs = { 'facecolor': figure.get_facecolor(), 'figsize': figure_dimensions, 'frameon': False } trajectory_kwargs = argument_groups.extract_arguments("trajectory_rendering", args) example_movie_rendering.render_trajectory_movie( movie_writer, basemap=mymap, trajectories=all_trajectories, dpi=args.dpi, figure=figure, filename=args.movie_file[0], num_frames=movie_kwargs['fps'] * movie_kwargs['duration'], start_time=movie_kwargs['start_time'], end_time=movie_kwargs['end_time'], trail_duration = datetime.timedelta(seconds=args.trail_duration), savefig_kwargs=savefig_kwargs, axes=axes, trajectory_rendering_args=trajectory_kwargs, highlight_trajectories=highlight_trajectories ) pyplot.close() return 0
def main(): logger = logging.getLogger(__name__) args = parse_args() mapmaker_kwargs = argument_groups.extract_arguments("mapmaker", args) # Some of the argument names for trajectory rendering are out of # sync with their command-line parameter names. We extract those # arguments manually at the render_annotated_trajectories # call instead of using extract_arguments("trajectory_rendering") # here. # Step 1: Load all the trajectories into memory. point_filename = args.point_data_file[0] field_assignments = extract_field_assignments(vars(args)) with open(point_filename, 'r') as infile: logger.info('Loading points and building trajectories.') trajectories = list( trajectories_from_point_file( infile, object_id_column=args.object_id_column, timestamp_column=args.timestamp_column, coordinate0_column=args.coordinate0, coordinate1_column=args.coordinate1, string_fields=field_assignments['string'], real_fields=field_assignments['real'], time_fields=field_assignments['time'], comment_character=args.comment_character, field_delimiter=args.delimiter, separation_distance=args.separation_distance, separation_time=datetime.timedelta( minutes=args.separation_time), minimum_length=args.minimum_length, domain=args.domain)) # Add the 'progress' annotation to all of our trajectories so # we have some way to color them trajectories = [annotations.progress(t) for t in trajectories] # We can compute the bounding box for Cartesian data automatically. # We don't need to do so for terrestrial data because the map will # default to the whole world. if (args.domain == 'cartesian2d' and (args.map_bbox is None or len(args.map_bbox) == 0)): args.map_bbox = geomath.compute_bounding_box( itertools.chain(*trajectories)) # # Step 3: Set up the map. # # There are a lot of keyword arguments for the map -- see # tracktable.script_helpers.argument_groups.mapmaker -- # so rather than pull them out individually like we did for # the point reader we extract the whole dict using # tracktable.script_helpers.argument_groups.extract_arguments(). logger.info('Initializing map canvas for rendering.') (figure, axes) = initialize_canvas(args.resolution, args.dpi) (mymap, map_artists) = mapmaker.mapmaker(**mapmaker_kwargs) if args.trajectory_linewidth == 'taper': linewidth_style = 'taper' linewidth = args.trajectory_initial_linewidth final_linewidth = args.trajectory_final_linewidth else: linewidth_style = 'constant' linewidth = args.trajectory_linewidth final_linewidth = linewidth # Eventually we will be able to use argument_groups.extract_arguments() for # this, but right now it's broken. Not all of the parameters in the # trajectory rendering argument group are supported and some of the names # have changed. # trajectory_rendering_kwargs = { 'decorate_head': args.decorate_trajectory_head, 'head_color': args.trajectory_head_color, 'head_size': args.trajectory_head_dot_size, 'color_map': args.trajectory_colormap, 'scalar': args.trajectory_color, 'scalar_min': args.scalar_min, 'scalar_max': args.scalar_max, 'linewidth_style': linewidth_style, 'linewidth': linewidth, 'final_linewidth': final_linewidth } render_annotated_trajectories(trajectories, mymap, **trajectory_rendering_kwargs) print("STATUS: Saving figure to file") pyplot.savefig(args.image_file[0], facecolor=figure.get_facecolor(), figsize=compute_figure_dimensions(args.resolution, args.dpi), dpi=args.dpi) pyplot.close() return 0
def main(): logger = logging.getLogger(__name__) # Step 0: Parse the command line arguments and grab sets we will need # later. args = parse_args() mapmaker_kwargs = argument_groups.extract_arguments("mapmaker", args) movie_kwargs = argument_groups.extract_arguments("movie_rendering", args) # Some of the keyword arguments for trajectory rendering have been renamed. # For now, we'll extract them by hand farther down in this function. # trajectory_rendering_kwargs = argument_groups.extract_arguments( # "trajectory_rendering", args) # Step 1: Load all the trajectories into memory. point_filename = args.point_data_file[0] field_assignments = extract_field_assignments(vars(args)) with open(point_filename, 'r') as infile: logger.info('Loading points and building trajectories.') trajectories = list( trajectories_from_point_file( infile, object_id_column=args.object_id_column, timestamp_column=args.timestamp_column, coordinate0_column=args.coordinate0, coordinate1_column=args.coordinate1, string_fields=field_assignments['string'], real_fields=field_assignments['real'], time_fields=field_assignments['time'], comment_character=args.comment_character, field_delimiter=args.delimiter, separation_distance=args.separation_distance, separation_time=datetime.timedelta(minutes=args.separation_time), minimum_length=args.minimum_length, domain=args.domain) ) # Add the 'progress' annotation to all of our trajectories so # we have some way to color them trajectories = [annotations.progress(t) for t in trajectories] # We can compute the bounding box for Cartesian data automatically. # We don't need to do so for terrestrial data because the map will # default to the whole world. if (args.domain == 'cartesian2d' and (args.map_bbox is None or len(args.map_bbox) == 0)): args.map_bbox = geomath.compute_bounding_box( itertools.chain(*trajectories) ) # # Step 3: Set up the map. # # There are a lot of keyword arguments for the map -- see # tracktable.script_helpers.argument_groups.mapmaker -- # so rather than pull them out individually like we did for # the point reader we extract the whole dict using # tracktable.script_helpers.argument_groups.extract_arguments(). logger.info('Initializing map canvas for rendering.') (figure, axes) = initialize_canvas(args.resolution, args.dpi) (mymap, map_artists) = mapmaker.mapmaker(**mapmaker_kwargs) # # Step 4: Set up the video encoder. # # movie_kwargs = argument_groups.extract_arguments("movie_rendering", args) movie_writer = setup_encoder(**movie_kwargs) # This set of arguments will be passed to the savefig() call that # grabs the latest movie frame. This is the place to put things # like background color, tight layout and friends. savefig_kwargs = {'facecolor': figure.get_facecolor(), 'figsize': compute_figure_dimensions(args.resolution, args.dpi), 'frameon': False} # # Lights! Camera! Action! # if args.trajectory_linewidth == 'taper': linewidth_style = 'taper' linewidth = args.trajectory_initial_linewidth final_linewidth = args.trajectory_final_linewidth else: linewidth_style = 'constant' linewidth = args.trajectory_linewidth final_linewidth = linewidth # Eventually we will be able to use argument_groups.extract_arguments() for # this, but right now it's broken. Not all of the parameters in the # trajectory rendering argument group are supported and some of the names # have changed. # trajectory_rendering_kwargs = { 'decorate_head': args.decorate_trajectory_head, 'head_color': args.trajectory_head_color, 'head_size': args.trajectory_head_dot_size, 'color_map': args.trajectory_colormap, 'scalar': args.trajectory_color, 'scalar_min': args.scalar_min, 'scalar_max': args.scalar_max, 'linewidth_style': linewidth_style, 'linewidth': linewidth, 'final_linewidth': final_linewidth } render_trajectory_movie( movie_writer, axes=mymap, trajectories=trajectories, dpi=args.dpi, figure=figure, filename=args.movie_file[0], num_frames=movie_kwargs['fps'] * movie_kwargs['duration'], start_time=movie_kwargs['start_time'], end_time=movie_kwargs['end_time'], trail_duration=datetime.timedelta(seconds=args.trail_duration), savefig_kwargs=savefig_kwargs, trajectory_rendering_kwargs=trajectory_rendering_kwargs, domain=args.domain ) pyplot.close() logger.info("Movie render complete. File saved to {}".format(args.movie_file[0])) return 0
def main(): args = parse_args() logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) dpi = args.dpi image_resolution = args.resolution figure_dimensions = [ float(image_resolution[0]) / dpi, float(image_resolution[1]) / dpi ] logger.info("Initializing image canvas.") figure = pyplot.figure(figsize=figure_dimensions, facecolor='black', edgecolor='black') axes = figure.add_axes([0, 0, 1, 1], frameon=False, facecolor='black') axes.set_frame_on(False) logger.info("Initializing point source.") point_filename = args.point_data_file[0] with open(point_filename, 'r') as infile: point_source = points_from_file( infile, args.coordinate0, args.coordinate1, comment_character=args.comment_character, field_delimiter=args.delimiter, domain=args.domain) # This is a little bit ugly but I don't yet know of a better way # to do it. If we want to automatically compute the bounding box # of the data points before we render anything we must read all the # points at least once. # # That gives us a choice: read them once and keep them all in # memory, or make one pass through the file to compute the # bounding box and then another to read and render the points? # # For the moment I elect to read the points and keep them in memory. if args.domain == 'cartesian2d': if args.map_bbox is None: logger.info(('Collecting points to compute Cartesian ' 'bounding box.')) point_source = list(point_source) data_bbox = geomath.compute_bounding_box(point_source) else: # The bounding box on the command line is # [x_min, y_min, x_max, y_max] data_bbox = cartesian2d.BoundingBox( (args.map_bbox[0], args.map_bbox[1]), (args.map_bbox[2], args.map_bbox[3]) ) else: # Default to taking the histogram bounds from the map extent. data_bbox = None if args.map_bbox is not None: # The bounding box on the command line is # [x_min, y_min, x_max, y_max] data_bbox = terrestrial.BoundingBox( (args.map_bbox[0], args.map_bbox[1]), (args.map_bbox[2], args.map_bbox[3]) ) logger.info("Creating map projection.") # There are a lot of keyword arguments for the map -- see # tracktable.script_helpers.argument_groups.mapmaker -- # so rather than pull them out individually like we did for # the point reader we extract the whole dict using # tracktable.script_helpers.argument_groups.extract_arguments(). mapmaker_kwargs = argument_groups.extract_arguments("mapmaker", args) (mymap, artists) = mapmaker.mapmaker(**mapmaker_kwargs) logger.info("Rendering histogram.") render_histogram(mymap, domain=args.domain, bounding_box=data_bbox, point_source=point_source, bin_size=args.histogram_bin_size, color_map=args.colormap, scale_type=args.scale) # We're done with the points so we exit the with: block where we held # the input file open. if args.title is not None: logger.info("Setting title: {}".format(args.title)) figure.suptitle(args.title, color='white') logger.info("STATUS: Saving figure to file") savefig_kwargs = {'figsize': figure_dimensions, 'dpi': dpi, 'facecolor': args.bgcolor } pyplot.savefig(args.image_file[0], **savefig_kwargs) pyplot.close() return 0
def configure_point_reader(infile, **kwargs): """Set up a TrajectoryPointReader for terrestrial points. Args: infile: An open file or file-like object containing the input. delimiter: A single character that separates fields. comment_character: Lines where this character is the first non-whitespace character will be ignored. coordinate_map: Map from coordinate number to column number. field_map: Mapping from field name to column number. See below for more details. Returns: The ready-to-use point reader. In order to actually retrieve the points, iterate over the contents of 'reader'. \note Coordinate Map You must tell the reader how to populate coordinates by supplying a coordinate->column map. Here is how you would tell it to use columns 10 and 11 for longitude and latitude (coordinates 0 and 1):: coordinate0 = 10 coordinate1 = 11 \note Field Map TrajectoryPoints can take named fields such as 'object_id', 'timestamp', 'altitude', 'airline_name', 'paint_color', 'time_plane_first_turned_on'... pretty much anything that can take a string, numeric or timestamp value. These are populated from columns in the file just like coordinates are. Here is an example: field_map = dict() field_map["object_id"] = 0 field_map["timestamp"] = 1 field_map["altitude"] = 4 field_map["speed"] = 5 field_map["airline_name"] = 6 TrajectoryPoint has 'object_id' and 'timestamp' as class members accessed with 'my_point.object_id' and 'my_point.timestamp'. All other named properties are accessed as 'my_point.properties["prop_name"]'. """ reader_args = extract_arguments('delimited_text_point_reader', kwargs) print("Arguments after extract(): {}".format(reader_args)) domain = reader_args['domain'] if domain.lower() not in ALL_DOMAINS: raise KeyError( "Domain '{}' is not in list of installed domains ({}).".format( domain, ', '.join(ALL_DOMAINS))) else: domain_to_import = 'tracktable.domain.{}'.format(domain.lower()) domain_module = importlib.import_module(domain_to_import) reader = domain_module.TrajectoryPointReader() reader.input = infile reader.comment_character = reader_args['comment_character'] reader.field_delimiter = reader_args['delimiter'] if reader_args['object_id_column'] is not None: reader.object_id_column = reader_args['object_id_column'] if reader_args['timestamp_column'] is not None: reader.timestamp_column = reader_args['timestamp_column'] if reader_args['coordinate0'] is not None: reader.coordinates[0] = int(reader_args['coordinate0']) if reader_args['coordinate1'] is not None: reader.coordinates[1] = int(reader_args['coordinate1']) if reader_args['coordinate2'] is not None: reader.coordinates[2] = int(reader_args['coordinate2']) if (reader_args['string_field_column'] is not None and len(reader_args['string_field_column']) > 0): for (field, column) in group(reader_args['string_field_column'], 2): reader.string_fields[field] = column if (reader_args['time_field_column'] is not None and len(reader_args['time_field_column']) > 0): for (field, column) in group(reader_args['time_field_column'], 2): reader.time_fields[field] = column if (reader_args['numeric_field_column'] is not None and len(reader_args['numeric_field_column']) > 0): for (field, column) in group(reader_args['numeric_field_column'], 2): reader.numeric_fields[field] = column return reader
def main(): args = parse_args() dpi = args.dpi image_resolution = args.resolution if image_resolution is None: image_resolution = [800, 600] figure_dimensions = [ float(image_resolution[0]) / dpi, float(image_resolution[1]) / dpi ] print("STATUS: Initializing canvas") figure = pyplot.figure(figsize=figure_dimensions, facecolor='black', edgecolor='black') axes = figure.add_axes([0, 0, 1, 1], frameon=False, axisbg='black') axes.set_frame_on(False) print("STATUS: Initializing point source") point_source = setup_point_source(args.point_data_file[0], args) # This is a little bit ugly but I don't yet know of a better way # to do it. If we want to automatically compute the bounding box # of the data points before we render anything we must read all the # points at least once. # # That gives us a choice: read them once and keep them all in # memory, or make one pass through the file to compute the # bounding box and then another to read and render the points? # # For the moment I elect to read the points and keep them in memory. data_bbox = None if args.domain == 'cartesian2d' and args.map_bbox is None: print("STATUS: Collecting points to compute bounding box") all_points = list(point_source) data_bbox = geomath.compute_bounding_box(all_points) point_source = all_points print("STATUS: Initializing map projection") mapmaker_kwargs = argument_groups.extract_arguments("mapmaker", args) (mymap, base_artists) = mapmaker.mapmaker(computed_bbox=data_bbox, **mapmaker_kwargs) print("STATUS: Initializing trajectory source") trajectory_source = setup_trajectory_source(point_source, args) print("STATUS: Collecting all trajectories") print("DEBUG: Trajectory source is a {}".format(type(trajectory_source))) all_trajectories = list(trajectory_source) print("STATUS: Done collecting trajectories") movie_kwargs = argument_groups.extract_arguments("movie_rendering", args) movie_writer = example_movie_rendering.setup_encoder(**movie_kwargs) # This set of arguments will be passed to the savefig() call that # grabs the latest movie frame. This is the place to put things # like background color, tight layout and friends. savefig_kwargs = { 'facecolor': figure.get_facecolor(), 'figsize': figure_dimensions, 'frameon': False } trajectory_kwargs = argument_groups.extract_arguments( "trajectory_rendering", args) example_movie_rendering.render_trajectory_movie( movie_writer, map_projection=mymap, trajectories=all_trajectories, dpi=args.dpi, figure=figure, filename=args.movie_file[0], num_frames=movie_kwargs['fps'] * movie_kwargs['duration'], start_time=movie_kwargs['start_time'], end_time=movie_kwargs['end_time'], trail_duration=datetime.timedelta(seconds=args.trail_duration), savefig_kwargs=savefig_kwargs, axes=axes, trajectory_rendering_args=trajectory_kwargs) pyplot.close() return 0
def main(): args = parse_args() dpi = args.dpi image_resolution = args.resolution figure_dimensions = [ float(image_resolution[0]) / dpi, float(image_resolution[1]) / dpi ] print("STATUS: Initializing image") figure = pyplot.figure(figsize=figure_dimensions, facecolor='black', edgecolor='black') axes = figure.add_axes([0, 0, 1, 1], frameon=False, axisbg='black') axes.set_frame_on(False) print("STATUS: Initializing point source") point_source = setup_point_source(args.point_data_file[0], args) # This is a little bit ugly but I don't yet know of a better way # to do it. If we want to automatically compute the bounding box # of the data points before we render anything we must read all the # points at least once. # # That gives us a choice: read them once and keep them all in # memory, or make one pass through the file to compute the # bounding box and then another to read and render the points? # # For the moment I elect to read the points and keep them in memory. if args.domain == 'cartesian2d' and args.map_bbox is None: print("STATUS: Collecting points to compute bounding box") all_points = [point for point in point_source] # list(point_source) data_bbox = geomath.compute_bounding_box(all_points) point_source = all_points args.map_bbox = data_bbox print("STATUS: Creating map projection") mapmaker_kwargs = argument_groups.extract_arguments("mapmaker", args) (mymap, artists) = mapmaker.mapmaker(**mapmaker_kwargs) print("STATUS: Rendering histogram") render_histogram(mymap, domain=args.domain, bounding_box=args.map_bbox, point_source=point_source, bin_size=args.histogram_bin_size, color_map=args.colormap, scale_type=args.scale) if args.title is not None: print("Setting title: {}".format(args.title)) figure.suptitle(args.title, color='white') print("STATUS: Saving figure to file") savefig_kwargs = { 'figsize': figure_dimensions, 'dpi': dpi, 'frameon': False, 'facecolor': args.bgcolor } pyplot.savefig(args.image_file[0], **savefig_kwargs) pyplot.close() return 0