def get_positioning_params(coords, canvas_width, canvas_height, fill_percentage=1.0):
    """
    Determine the scale and offset required to center coordinates in a box.

    The returned parameters will always ensure that the coordinates are
    within the limits of the box and that aspect ratio is preserved.

    Parameters
    ----------

    coords: iterable
        Each value in coords is a tuple (x, y) representing a point from
        the original set of coordinates that require adjustment. The
        original iterable will not be modified.

    canvas_width: float
    canvas_height: float
        The dimensions of the canvas that the coordinates will be
        positioned on.

    fill_percentage: float [default=1.0]
        If set to a value less than 1.0, the coordinates will only fill
        a percentage of the canvas. For example, a canvas height of 10
        and fill percentage of 0.8 will scale the y-values from 1 to 9;
        this range (8) covers 80% of the canvas height and still
        centers the coordinates in the overall canvas.

    Returns
    -------

    scale: float
    x_offset: float
    y_offset: float

        In order to position the points appropriately, apply the
        following transformation:

        (x, y) -> ((scale * x) + x_offset, (scale * y) + y_offset)
    """
    if fill_percentage <= 0:
        raise ValueError(f"fill percentage must be >0, got {fill_percentage}")
    elif fill_percentage > 1:
        raise ValueError(f"fill percentage must be <=1, got {fill_percentage}")

    width = canvas_width * fill_percentage
    height = canvas_height * fill_percentage

    x_vals = []
    y_vals = []
    for x_val, y_val in coords:
        x_vals.append(x_val)
        y_vals.append(y_val)

    x_min = min(x_vals)
    x_max = max(x_vals)
    y_min = min(y_vals)
    y_max = max(y_vals)

    dx = x_max - x_min
    dy = y_max - y_min

    if dx > 0 and dy > 0:
        scale = min(width / dx, height / dy)
    else:
        scale = 1

    x_center = (x_min + x_max) / 2
    y_center = (y_min + y_max) / 2

    x_offset = (canvas_width / 2) - x_center * scale
    y_offset = (canvas_height / 2) - y_center * scale

    return scale, x_offset, y_offset