Scale a figure and translate it to sub-region of the original
    figure canvas.

    Note: If the input figure has a title, this title is converted into an
    annotation and scaled along with the rest of the figure.

    Note: This function mutates the input fig dict

    Note: This function assumes that the normalize_subplot_ids function has
    already been run on the figure, so that all layout subplot properties in
    use are explicitly present in the figure's layout.

    Parameters
    ----------
    fig: dict
        A plotly figure dict
    scale_x: float
        Factor by which to scale the figure in the x-direction. This will
        typically be a value < 1.  E.g. a value of 0.5 will cause the
        resulting figure to be half as wide as the original.
    scale_y: float
        Factor by which to scale the figure in the y-direction. This will
        typically be a value < 1
    translate_x: float
        Factor by which to translate the scaled figure in the x-direction in
        normalized coordinates.
    translate_y: float
        Factor by which to translate the scaled figure in the x-direction in
        normalized coordinates.

def _scale_translate(fig, scale_x, scale_y, translate_x, translate_y):
    """
    Scale a figure and translate it to sub-region of the original
    figure canvas.

    Note: If the input figure has a title, this title is converted into an
    annotation and scaled along with the rest of the figure.

    Note: This function mutates the input fig dict

    Note: This function assumes that the normalize_subplot_ids function has
    already been run on the figure, so that all layout subplot properties in
    use are explicitly present in the figure's layout.

    Parameters
    ----------
    fig: dict
        A plotly figure dict
    scale_x: float
        Factor by which to scale the figure in the x-direction. This will
        typically be a value < 1.  E.g. a value of 0.5 will cause the
        resulting figure to be half as wide as the original.
    scale_y: float
        Factor by which to scale the figure in the y-direction. This will
        typically be a value < 1
    translate_x: float
        Factor by which to translate the scaled figure in the x-direction in
        normalized coordinates.
    translate_y: float
        Factor by which to translate the scaled figure in the x-direction in
        normalized coordinates.
    """
    data = fig.setdefault('data', [])
    layout = fig.setdefault('layout', {})

    def scale_translate_x(x):
        return [x[0] * scale_x + translate_x,
                x[1] * scale_x + translate_x]

    def scale_translate_y(y):
        return [y[0] * scale_y + translate_y,
                y[1] * scale_y + translate_y]

    def perform_scale_translate(obj):
        domain = obj.setdefault('domain', {})
        x = domain.get('x', [0, 1])
        y = domain.get('y', [0, 1])

        domain['x'] = scale_translate_x(x)
        domain['y'] = scale_translate_y(y)

    # Scale/translate traces
    for trace in data:
        trace_type = trace.get('type', 'scatter')
        if trace_type in _domain_trace_types:
            perform_scale_translate(trace)

    # Scale/translate subplot containers
    for prop in layout:
        for subplot_type in _subplot_types:
            if prop.startswith(subplot_type):
                perform_scale_translate(layout[prop])

    for prop in layout:
        if prop.startswith('xaxis'):
            xaxis = layout[prop]
            x_domain = xaxis.get('domain', [0, 1])
            xaxis['domain'] = scale_translate_x(x_domain)
        elif prop.startswith('yaxis'):
            yaxis = layout[prop]
            y_domain = yaxis.get('domain', [0, 1])
            yaxis['domain'] = scale_translate_y(y_domain)

    # convert title to annotation
    # This way the annotation will be scaled with the reset of the figure
    annotations = layout.get('annotations', [])

    title = layout.pop('title', None)
    if title:
        titlefont = layout.pop('titlefont', {})
        title_fontsize = titlefont.get('size', 17)
        min_fontsize = 12
        titlefont['size'] = round(min_fontsize +
                                  (title_fontsize - min_fontsize) * scale_x)

        annotations.append({
            'text': title,
            'showarrow': False,
            'xref': 'paper',
            'yref': 'paper',
            'x': 0.5,
            'y': 1.01,
            'xanchor': 'center',
            'yanchor': 'bottom',
            'font': titlefont
        })
        layout['annotations'] = annotations

    # annotations
    for obj in layout.get('annotations', []):
        if obj.get('xref', None) == 'paper':
            obj['x'] = obj.get('x', 0.5) * scale_x + translate_x
            obj['y'] = obj.get('y', 0.5) * scale_y + translate_y