diff --git a/README.md b/README.md index 03f3c49..95af45c 100644 --- a/README.md +++ b/README.md @@ -287,8 +287,8 @@ result. The plot is saved using the matplotlib API. ```python import matplotlib.pyplot as plt - from asreview import open_state + from asreviewcontrib.insights.plot import plot_recall with open_state("example.asreview") as s: @@ -309,8 +309,8 @@ It's straightforward to customize the plots if you are familiar with ```python import matplotlib.pyplot as plt - from asreview import open_state + from asreviewcontrib.insights.plot import plot_wss with open_state("example.asreview") as s: @@ -332,8 +332,8 @@ knowledge is excluded from the plot. ```python import matplotlib.pyplot as plt - from asreview import open_state + from asreviewcontrib.insights.plot import plot_wss with open_state("example.asreview") as s: @@ -350,8 +350,8 @@ change this behavior. The arguments are identical for each plot function. ```python import matplotlib.pyplot as plt - from asreview import open_state + from asreviewcontrib.insights.plot import plot_wss with open_state("example.asreview") as s: @@ -362,7 +362,30 @@ with open_state("example.asreview") as s: fig.savefig("example_absolute_axis.png") ``` -![Recall with absolute axes](https://github.com/asreview/asreview-insights/blob/main/docs/example_absolute_axes.png) +![Recall with absolute +axes](https://github.com/asreview/asreview-insights/blob/main/docs/example_absolute_axes.png) + +#### Example: Adjusting the Random and Perfect curves + +By default, each plot will have a curve representing perfect performance, and a +curve representing random sampling performance. Both curves can be removed from +the graph. + +```python +import matplotlib.pyplot as plt +from asreview import open_state + +from asreviewcontrib.insights.plot import plot_recall + +with open_state("example.asreview") as s: + + fig, ax = plt.subplots() + plot_recall(ax, s, show_random=False, show_perfect=False) + + fig.savefig("example_without_curves.png") +``` + +![Recall with absolute axes](https://github.com/asreview/asreview-insights/blob/main/docs/example_without_curves.png) #### Example: Legend for multiple curves in one plot diff --git a/asreviewcontrib/insights/plot.py b/asreviewcontrib/insights/plot.py index 80f06a9..9dd8600 100644 --- a/asreviewcontrib/insights/plot.py +++ b/asreviewcontrib/insights/plot.py @@ -13,6 +13,7 @@ def plot_recall( x_absolute=False, y_absolute=False, show_random=True, + show_perfect=True, show_legend=True, legend_values=None, legend_kwargs=None, @@ -34,6 +35,8 @@ def plot_recall( If False, the fraction of all included records found is on the y-axis. show_random: bool Show the random curve in the plot. + show_perfect: bool + Show the perfect curve in the plot. show_legend: bool If state_obj contains multiple states, show a legend in the plot. legend_values: list[str] @@ -61,6 +64,7 @@ def plot_recall( x_absolute=x_absolute, y_absolute=y_absolute, show_random=show_random, + show_perfect=show_perfect, show_legend=show_legend, legend_values=legend_values, legend_kwargs=legend_kwargs, @@ -237,6 +241,7 @@ def _plot_recall( x_absolute=False, y_absolute=False, show_random=True, + show_perfect=True, show_legend=True, legend_values=None, legend_kwargs=None, @@ -258,7 +263,10 @@ def _plot_recall( ax = _add_recall_info(ax, labels, x_absolute, y_absolute) if show_random: - ax = _add_random_curve(ax, labels, x_absolute, y_absolute) + ax = _add_random_curve(ax, labels, x_absolute, y_absolute) + + if show_perfect: + ax = _add_perfect_curve(ax, labels, x_absolute, y_absolute) if show_legend: if legend_kwargs is None: @@ -398,6 +406,33 @@ def _add_random_curve(ax, labels, x_absolute, y_absolute): return ax +def _add_perfect_curve(ax, labels, x_absolute, y_absolute): + """Add a perfect curve to a plot using step-wise increments. + + Returns + ------- + plt.axes.Axes + Axes with perfect curve added. + """ + # get total amount of positive labels + if isinstance(labels[0], list): + n_pos_docs = max(sum(label_set) for label_set in labels) + n_docs = max(len(label_set) for label_set in labels) + else: + n_pos_docs = sum(labels) + n_docs = len(labels) + + # Create x and y arrays for step plot + x = np.arange(0, n_pos_docs + 1) if x_absolute else np.arange(0, n_pos_docs + 1) / n_docs # noqa: E501 + y = np.arange(0, n_pos_docs + 1) if y_absolute else np.arange(0, n_pos_docs + 1) / n_pos_docs # noqa: E501 + + # Plot the stepwise perfect curve + ax.step(x, y, color="grey", where="post") + + return ax + + + def _add_wss_curve(ax, labels, x_absolute=False, y_absolute=False, legend_label=None): x, y = _wss_values(labels, x_absolute=x_absolute, y_absolute=y_absolute) ax.step(x, y, where="post", label=legend_label) diff --git a/docs/example_without_curves.png b/docs/example_without_curves.png new file mode 100644 index 0000000..2a394f5 Binary files /dev/null and b/docs/example_without_curves.png differ diff --git a/docs/example_without_curves.py b/docs/example_without_curves.py new file mode 100644 index 0000000..1b8d70b --- /dev/null +++ b/docs/example_without_curves.py @@ -0,0 +1,10 @@ +import matplotlib.pyplot as plt +from asreview import open_state + +from asreviewcontrib.insights.plot import plot_recall + +with open_state("tests/asreview_files/sim_van_de_schoot_2017_logistic.asreview") as s: + fig, ax = plt.subplots() + plot_recall(ax, s, show_random=False, show_perfect=False) + + fig.savefig("docs/example_without_curves.png")