from ladybug_rhino.togeometry import to_point3d
    from ladybug_rhino.fromgeometry import from_mesh3d, from_mesh2d, \
        from_polyline2d, from_linesegment2d
    from ladybug_rhino.text import text_objects
    from ladybug_rhino.fromobjects import legend_objects
    from ladybug_rhino.grasshopper import all_required_inputs, list_to_data_tree
except ImportError as e:
    raise ImportError('\nFailed to import ladybug_rhino:\n\t{}'.format(e))


if all_required_inputs(ghenv.Component):
    # apply any analysis periods and conditional statements to the input collections
    if period_ is not None:
        _data = [coll.filter_by_analysis_period(period_) for coll in _data]
    if statement_ is not None:
        _data = HourlyContinuousCollection.filter_collections_by_statement(
            _data, statement_)

    # set default values for the chart dimensions
    _base_pt_ = to_point3d(_base_pt_) if _base_pt_ is not None else Point3D()
    _x_dim_ = _x_dim_ if _x_dim_ is not None else 1.0 / conversion_to_meters()
    _y_dim_ = _y_dim_ if _y_dim_ is not None else 4.0 / conversion_to_meters()
    _z_dim_ = _z_dim_ if _z_dim_ is not None else 0
    reverse_y_ = reverse_y_ if reverse_y_ is not None else False

    # empty lists of objects to be filled with visuals
    mesh, title, all_legends, all_borders, all_labels = [], [], [], [], []

    for i, data_coll in enumerate(_data):
        try:  # sense when several legend parameters are connected
            lpar = legend_par_[i]
        except IndexError:
        '{} ({})'.format(data_col.header.data_type, data_col.header.unit)
    ]
    for key, val in data_col.header.metadata.items():
        title_array.append('{}: {}'.format(key, val))
    title_array.append('period: {}'.format(data_col.header.analysis_period))
    return '\n'.join(title_array)


if all_required_inputs(ghenv.Component):
    # Apply any analysis periods and conditional statement to the input collections
    if period_ is not None:
        _data = [dat.filter_by_analysis_period(period_) for dat in _data]
        _wind_direction = _wind_direction.filter_by_analysis_period(period_)

    if statement_ is not None and statement_.strip() != "":
        _fdata = HourlyContinuousCollection.filter_collections_by_statement(
            _data + [_wind_direction], statement_)
        _data = _fdata[:-1]
        _wind_direction = _fdata[-1]

    # filter zero speed values out of collections if speed is input
    pattern = []
    filt_wind_dir = _wind_direction
    for dat in _data:
        if isinstance(dat.header.data_type, Speed):
            for val in dat.values:
                pat = True if val > 1e-10 else False
                pattern.append(pat)
            break
    if len(pattern) != 0:
        for i, dat in enumerate(_data):
            if not isinstance(dat.header.data_type, Speed):