# Buggy code
def plot_diagram(diagram, homology_dimensions=None, plotly_params=None):
    """Plot a single persistence diagram.

    Parameters
    ----------
    diagram : ndarray of shape (n_points, 3)
        The persistence diagram to plot, where the third dimension along axis 1
        contains homology dimensions, and the first two contain (birth, death)
        pairs to be used as coordinates in the two-dimensional plot.

    homology_dimensions : list of int or None, optional, default: ``None``
        Homology dimensions which will appear on the plot. If ``None``, all
        homology dimensions which appear in `diagram` will be plotted.

    plotly_params : dict or None, optional, default: ``None``
        Custom parameters to configure the plotly figure. Allowed keys are
        ``"traces"`` and ``"layout"``, and the corresponding values should be
        dictionaries containing keyword arguments as would be fed to the
        :meth:`update_traces` and :meth:`update_layout` methods of
        :class:`plotly.graph_objects.Figure`.

    Returns
    -------
    fig : :class:`plotly.graph_objects.Figure` object
        Figure representing the persistence diagram.

    """
    # TODO: increase the marker size
    if homology_dimensions is None:
        homology_dimensions = np.unique(diagram[:, 2])

    diagram_no_dims = diagram[:, :2]
    max_val_display = np.max(
        np.where(np.isposinf(diagram_no_dims), -np.inf, diagram_no_dims)
    )
    min_val_display = np.min(
        np.where(np.isneginf(diagram_no_dims), np.inf, diagram_no_dims)
    )
    parameter_range = max_val_display - min_val_display
    extra_space = 0.02 * parameter_range
    min_val_display -= extra_space
    max_val_display += extra_space

    fig = gobj.Figure()
    fig.add_trace(
        gobj.Scatter(
            x=[min_val_display, max_val_display],
            y=[min_val_display, max_val_display],
            mode="lines",
            line={"dash": "dash", "width": 1, "color": "black"},
            showlegend=False,
            hoverinfo="none",
        )
    )

    for dim in homology_dimensions:
        name = f"H{int(dim)}" if dim != np.inf else "Any homology dimension"
        subdiagram = diagram[diagram[:, 2] == dim]
        diff = subdiagram[:, 1] != subdiagram[:, 0]
        subdiagram = subdiagram[diff]
        fig.add_trace(
            gobj.Scatter(
                x=subdiagram[:, 0], y=subdiagram[:, 1], mode="markers", name=name
            )
        )

    fig.update_layout(
        width=500,
        height=500,
        xaxis1={
            "title": "Birth",
            "side": "bottom",
            "type": "linear",
            "range": [min_val_display, max_val_display],
            "autorange": False,
            "ticks": "outside",
            "showline": True,
            "zeroline": True,
            "linewidth": 1,
            "linecolor": "black",
            "mirror": False,
            "showexponent": "all",
            "exponentformat": "e",
        },
        yaxis1={
            "title": "Death",
            "side": "left",
            "type": "linear",
            "range": [min_val_display, max_val_display],
            "autorange": False,
            "scaleanchor": "x",
            "scaleratio": 1,
            "ticks": "outside",
            "showline": True,
            "zeroline": True,
            "linewidth": 1,
            "linecolor": "black",
            "mirror": False,
            "showexponent": "all",
            "exponentformat": "e",
        },
        plot_bgcolor="white",
    )

    # Update traces and layout according to user input
    if plotly_params:
        fig.update_traces(plotly_params.get("traces", None))
        fig.update_layout(plotly_params.get("layout", None))

    return fig


# Traceback (TypeError)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-5-5e233492b878> in <module>
----> 1 Amplitude(metric="persistence_image").fit_transform(Xd)

~\Workspace\giotto-tda_ulupo\gtda\utils\_docs.py in fit_transform_wrapper(*args, **kwargs)
104         @wraps(original_fit_transform)
105         def fit_transform_wrapper(*args, **kwargs):
--> 106             return original_fit_transform(*args, **kwargs)
107         fit_transform_wrapper.__doc__ = \
108             make_fit_transform_docs(fit_docs, transform_docs)

~\Anaconda3\envs\gtda-ulupo-py38\lib\site-packages\sklearn\base.py in fit_transform(self, X, y, **fit_params)
688         if y is None:
689             # fit method of arity 1 (unsupervised transformation)
--> 690             return self.fit(X, **fit_params).transform(X)
691         else:
692             # fit method of arity 2 (supervised transformation)

~\Workspace\giotto-tda_ulupo\gtda\diagrams\features.py in fit(self, X, y)
273         if self.metric == 'persistence_image':
274             self.effective_metric_params_['weights'] = \
--> 275                 _calculate_weights(X, **self.effective_metric_params_)
276
277         return self

TypeError: _calculate_weights() missing 1 required positional argument: 'weight_function'

# Fixed code
def plot_diagram(diagram, homology_dimensions=None, plotly_params=None):
    """Plot a single persistence diagram.

    Parameters
    ----------
    diagram : ndarray of shape (n_points, 3)
        The persistence diagram to plot, where the third dimension along axis 1
        contains homology dimensions, and the first two contain (birth, death)
        pairs to be used as coordinates in the two-dimensional plot.

    homology_dimensions : list of int or None, optional, default: ``None``
        Homology dimensions which will appear on the plot. If ``None``, all
        homology dimensions which appear in `diagram` will be plotted.

    plotly_params : dict or None, optional, default: ``None``
        Custom parameters to configure the plotly figure. Allowed keys are
        ``"traces"`` and ``"layout"``, and the corresponding values should be
        dictionaries containing keyword arguments as would be fed to the
        :meth:`update_traces` and :meth:`update_layout` methods of
        :class:`plotly.graph_objects.Figure`.

    Returns
    -------
    fig : :class:`plotly.graph_objects.Figure` object
        Figure representing the persistence diagram.

    """
    # TODO: increase the marker size
    if homology_dimensions is None:
        homology_dimensions = np.unique(diagram[:, 2])

    diagram_no_dims = diagram[:, :2]
    max_val_display = np.max(
        np.where(np.isposinf(diagram_no_dims), -np.inf, diagram_no_dims)
    )
    min_val_display = np.min(
        np.where(np.isneginf(diagram_no_dims), np.inf, diagram_no_dims)
    )
    parameter_range = max_val_display - min_val_display
    extra_space = 0.02 * parameter_range
    min_val_display -= extra_space
    max_val_display += extra_space

    fig = gobj.Figure()
    fig.add_trace(
        gobj.Scatter(
            x=[min_val_display, max_val_display],
            y=[min_val_display, max_val_display],
            mode="lines",
            line={"dash": "dash", "width": 1, "color": "black"},
            showlegend=False,
            hoverinfo="none",
        )
    )

    for dim in homology_dimensions:
        name = f"H{int(dim)}" if dim != np.inf else "Any homology dimension"
        subdiagram = diagram[diagram[:, 2] == dim]
        diff = subdiagram[:, 1] != subdiagram[:, 0]
        subdiagram = subdiagram[diff]
        unique, inverse, counts = np.unique(
            subdiagram, axis=0, return_inverse=True, return_counts=True
        )
        hovertext = [
            f"{tuple(unique[unique_row_index][:2])}"
            + (
                f", multiplicity: {counts[unique_row_index]}"
                if counts[unique_row_index] > 1
                else ""
            )
            for unique_row_index in inverse
        ]
        fig.add_trace(
            gobj.Scatter(
                x=subdiagram[:, 0],
                y=subdiagram[:, 1],
                mode="markers",
                hoverinfo="text",
                hovertext=hovertext,
                name=name,
            )
        )

    fig.update_layout(
        width=500,
        height=500,
        xaxis1={
            "title": "Birth",
            "side": "bottom",
            "type": "linear",
            "range": [min_val_display, max_val_display],
            "autorange": False,
            "ticks": "outside",
            "showline": True,
            "zeroline": True,
            "linewidth": 1,
            "linecolor": "black",
            "mirror": False,
            "showexponent": "all",
            "exponentformat": "e",
        },
        yaxis1={
            "title": "Death",
            "side": "left",
            "type": "linear",
            "range": [min_val_display, max_val_display],
            "autorange": False,
            "scaleanchor": "x",
            "scaleratio": 1,
            "ticks": "outside",
            "showline": True,
            "zeroline": True,
            "linewidth": 1,
            "linecolor": "black",
            "mirror": False,
            "showexponent": "all",
            "exponentformat": "e",
        },
        plot_bgcolor="white",
    )

    # Update traces and layout according to user input
    if plotly_params:
        fig.update_traces(plotly_params.get("traces", None))
        fig.update_layout(plotly_params.get("layout", None))

    return fig