Skip to content

Commit

Permalink
Added summary bars and edited aesthetic of contrast and swarm bars
Browse files Browse the repository at this point in the history
  • Loading branch information
JAnns98 committed Apr 12, 2024
1 parent 7bda513 commit cb28e6c
Show file tree
Hide file tree
Showing 4 changed files with 128 additions and 40 deletions.
15 changes: 11 additions & 4 deletions dabest/_effsize_objects.py
Expand Up @@ -1022,6 +1022,8 @@ def plot(
swarm_bars=True,
contrast_bars_kwargs=None,
swarm_bars_kwargs=None,
summary_bars=None,
summary_bars_kwargs=None,
):
"""
Creates an estimation plot for the effect size of interest.
Expand Down Expand Up @@ -1171,14 +1173,19 @@ def plot(
swarm_bars : boolean, default True
Whether or not to display the swarm bars.
contrast_bars_kwargs : dict, default None
Pass relevant keyword arguments to the contrast bars. Pass any keyword argumentd accepted by
Pass relevant keyword arguments to the contrast bars. Pass any keyword arguments accepted by
matplotlib.patches.Rectangle here, as a string. If None, the following keywords are passed:
{"color": None, "alpha": 0.1}
{"color": None, "alpha": 0.15}
swarm_bars_kwargs : dict, default None
Pass relevant keyword arguments to the swarm bars. Pass any keyword argumentd accepted by
Pass relevant keyword arguments to the swarm bars. Pass any keyword arguments accepted by
matplotlib.patches.Rectangle here, as a string. If None, the following keywords are passed:
{"color": None, "alpha": 0.15}
{"color": None, "alpha": 0.1}
summary_bars : list, default None
Pass a list of indices of the contrast objects to have summary bars displayed on the plot.
For example, [0,1] will show summary bars for the first two contrast objects.
summary_bars_kwargs: dict, default None
If None, the following keywords are passed: {"color": None, "alpha": 0.15}
Returns
-------
Expand Down
69 changes: 53 additions & 16 deletions dabest/plotter.py
Expand Up @@ -53,7 +53,10 @@ def effectsize_df_plotter(effectsize_df, **plot_kwargs):
title=None, fontsize_title=16,
fontsize_rawxlabel=12, fontsize_rawylabel=12,
fontsize_contrastxlabel=12, fontsize_contrastylabel=12,
fontsize_delta2label=12
fontsize_delta2label=12,
swarm_bars=True, swarm_bars_kwargs=None,
contrast_bars=True, contrast_bars_kwargs=None,
"""
from .misc_tools import merge_two_dicts
from .plot_tools import (
Expand Down Expand Up @@ -1591,7 +1594,7 @@ def effectsize_df_plotter(effectsize_df, **plot_kwargs):

####################################################### END GRIDKEY MAIN CODE WIP

################################################### Contrast Bars WIP
################################################### Swarm & Contrast Bars WIP

# Swarm Bars WIP
swarm_bars = plot_kwargs["swarm_bars"]
Expand All @@ -1615,14 +1618,11 @@ def effectsize_df_plotter(effectsize_df, **plot_kwargs):
swarm_bars_order = pd.unique(plot_data[xvar])

swarm_means = plot_data.groupby(xvar)[yvar].mean().reindex(index=swarm_bars_order)
swarm_bar_colors = [swarm_bars_kwargs.get('color')]*(len(swarm_bars_order)+1) if swarm_bars_kwargs.get('color') is not None else ['black']*(len(swarm_bars_order)+1) if color_col is not None or is_paired else swarm_colors
swarm_bars_colors = [swarm_bars_kwargs.get('color')]*(len(swarm_bars_order)+1) if swarm_bars_kwargs.get('color') is not None else ['black']*(len(swarm_bars_order)+1) if color_col is not None or is_paired else swarm_colors
swarm_bars_kwargs.pop('color')
for swarm_bars_x,swarm_bars_y,c in zip(np.arange(0,len(swarm_bars_order)+1,1), swarm_means, swarm_bar_colors):
rawdata_axes.add_patch(mpatches.Rectangle((swarm_bars_x-0.2,0),
0.5-0.1, swarm_bars_y, zorder=-1,color=c,**swarm_bars_kwargs))

else:
pass
for swarm_bars_x,swarm_bars_y,c in zip(np.arange(0,len(swarm_bars_order)+1,1), swarm_means, swarm_bars_colors):
rawdata_axes.add_patch(mpatches.Rectangle((swarm_bars_x-0.25,0),
0.5, swarm_bars_y, zorder=-1,color=c,**swarm_bars_kwargs))

# Contrast Bars WIP
contrast_bars = plot_kwargs["contrast_bars"]
Expand All @@ -1636,21 +1636,58 @@ def effectsize_df_plotter(effectsize_df, **plot_kwargs):
for j, tick in enumerate(ticks_to_plot):
contrast_means.append(results.difference[j])

contrast_bar_colors = [contrast_bars_kwargs.get('color')]*(len(ticks_to_plot)+1) if contrast_bars_kwargs.get('color') is not None else ['black']*(max(ticks_to_plot)+1) if color_col is not None or (proportional and is_paired) or is_paired else swarm_colors
contrast_bars_colors = [contrast_bars_kwargs.get('color')]*(len(ticks_to_plot)+1) if contrast_bars_kwargs.get('color') is not None else ['black']*(max(ticks_to_plot)+1) if color_col is not None or (proportional and is_paired) or is_paired else swarm_colors
contrast_bars_kwargs.pop('color')
for contrast_bars_x,contrast_bars_y in zip(ticks_to_plot, contrast_means):
contrast_axes.add_patch(mpatches.Rectangle((contrast_bars_x,0),0.25, contrast_bars_y, zorder=-1, color=contrast_bar_colors[contrast_bars_x], **contrast_bars_kwargs))
contrast_axes.add_patch(mpatches.Rectangle((contrast_bars_x-0.25,0),0.5, contrast_bars_y, zorder=-1, color=contrast_bars_colors[contrast_bars_x], **contrast_bars_kwargs))

if show_mini_meta:
contrast_axes.add_patch(mpatches.Rectangle((max(rawdata_axes.get_xticks())+2,0),0.25, mini_meta_delta.difference, zorder=-1, color='black', **contrast_bars_kwargs))
contrast_axes.add_patch(mpatches.Rectangle((max(rawdata_axes.get_xticks())+2-0.25,0),0.5, mini_meta_delta.difference, zorder=-1, color='black', **contrast_bars_kwargs))

if show_delta2:
contrast_axes.add_patch(mpatches.Rectangle((max(rawdata_axes.get_xticks())+2,0),0.25, delta_delta.difference, zorder=-1, color='black', **contrast_bars_kwargs))
contrast_axes.add_patch(mpatches.Rectangle((max(rawdata_axes.get_xticks())+2-0.25,0),0.5, delta_delta.difference, zorder=-1, color='black', **contrast_bars_kwargs))

################################################### Swarm & Contrast Bars WIP

################################################### Summary Bars WIP

summary_bars = plot_kwargs["summary_bars"]
default_summary_bars_kwargs = {"color": None, "alpha": 0.15}
if plot_kwargs["summary_bars_kwargs"] is None:
summary_bars_kwargs = default_summary_bars_kwargs
else:
pass

################################################### Contrast Bars WIP
summary_bars_kwargs = merge_two_dicts(default_summary_bars_kwargs, plot_kwargs["summary_bars_kwargs"])

if summary_bars is not None:
if not isinstance(summary_bars, list):
raise TypeError("summary_bars must be a list of indices (ints).")
if not all(isinstance(i, int) for i in summary_bars):
raise TypeError("summary_bars must be a list of indices (ints).")
if any(i >= len(results) for i in summary_bars):
raise ValueError("Index {} chosen is out of range for the contrast objects.".format([i for i in summary_bars if i >= len(results)]))
if float_contrast:
raise ValueError("summary_bars cannot be used with Gardner-Altman plots.")
else:
print('Summary plots WIP')
summary_xmin, summary_xmax = contrast_axes.get_xlim()
summary_bars_colors = [summary_bars_kwargs.get('color')]*(len(summary_bars)+1) if summary_bars_kwargs.get('color') is not None else ['black']*(max(summary_bars)+1) if color_col is not None or (proportional and is_paired) or is_paired else swarm_colors
summary_bars_kwargs.pop('color')
for summary_index in summary_bars:
print('Summary plot for contrast object:', summary_index)
if ci_type == "bca":
summary_ci_low = results.bca_low[summary_index]
summary_ci_high = results.bca_high[summary_index]
else:
summary_ci_low = results.pct_low[summary_index]
summary_ci_high = results.pct_high[summary_index]

summary_color = summary_bars_colors[ticks_to_plot[summary_index]]

contrast_axes.add_patch(mpatches.Rectangle((summary_xmin,summary_ci_low),summary_xmax+1,
summary_ci_high-summary_ci_low, zorder=-2, color=summary_color, **summary_bars_kwargs))


################################################### Summary Bars WIP

# Make sure no stray ticks appear!
rawdata_axes.xaxis.set_ticks_position("bottom")
Expand Down
15 changes: 11 additions & 4 deletions nbs/API/effsize_objects.ipynb
Expand Up @@ -1183,6 +1183,8 @@
" swarm_bars=True,\n",
" contrast_bars_kwargs=None,\n",
" swarm_bars_kwargs=None,\n",
" summary_bars=None,\n",
" summary_bars_kwargs=None,\n",
" ):\n",
" \"\"\"\n",
" Creates an estimation plot for the effect size of interest.\n",
Expand Down Expand Up @@ -1332,14 +1334,19 @@
" swarm_bars : boolean, default True\n",
" Whether or not to display the swarm bars.\n",
" contrast_bars_kwargs : dict, default None\n",
" Pass relevant keyword arguments to the contrast bars. Pass any keyword argumentd accepted by \n",
" Pass relevant keyword arguments to the contrast bars. Pass any keyword arguments accepted by \n",
" matplotlib.patches.Rectangle here, as a string. If None, the following keywords are passed:\n",
" {\"color\": None, \"alpha\": 0.1}\n",
" {\"color\": None, \"alpha\": 0.15}\n",
" swarm_bars_kwargs : dict, default None\n",
" Pass relevant keyword arguments to the swarm bars. Pass any keyword argumentd accepted by \n",
" Pass relevant keyword arguments to the swarm bars. Pass any keyword arguments accepted by \n",
" matplotlib.patches.Rectangle here, as a string. If None, the following keywords are passed:\n",
" {\"color\": None, \"alpha\": 0.15}\n",
" {\"color\": None, \"alpha\": 0.1}\n",
"\n",
" summary_bars : list, default None\n",
" Pass a list of indices of the contrast objects to have summary bars displayed on the plot.\n",
" For example, [0,1] will show summary bars for the first two contrast objects.\n",
" summary_bars_kwargs: dict, default None\n",
" If None, the following keywords are passed: {\"color\": None, \"alpha\": 0.15}\n",
"\n",
" Returns\n",
" -------\n",
Expand Down
69 changes: 53 additions & 16 deletions nbs/API/plotter.ipynb
Expand Up @@ -112,7 +112,10 @@
" title=None, fontsize_title=16,\n",
" fontsize_rawxlabel=12, fontsize_rawylabel=12,\n",
" fontsize_contrastxlabel=12, fontsize_contrastylabel=12,\n",
" fontsize_delta2label=12\n",
" fontsize_delta2label=12,\n",
" swarm_bars=True, swarm_bars_kwargs=None,\n",
" contrast_bars=True, contrast_bars_kwargs=None,\n",
"\n",
" \"\"\"\n",
" from .misc_tools import merge_two_dicts\n",
" from .plot_tools import (\n",
Expand Down Expand Up @@ -1650,7 +1653,7 @@
"\n",
" ####################################################### END GRIDKEY MAIN CODE WIP\n",
" \n",
" ################################################### Contrast Bars WIP\n",
" ################################################### Swarm & Contrast Bars WIP\n",
" \n",
" # Swarm Bars WIP\n",
" swarm_bars = plot_kwargs[\"swarm_bars\"]\n",
Expand All @@ -1674,14 +1677,11 @@
" swarm_bars_order = pd.unique(plot_data[xvar])\n",
"\n",
" swarm_means = plot_data.groupby(xvar)[yvar].mean().reindex(index=swarm_bars_order)\n",
" swarm_bar_colors = [swarm_bars_kwargs.get('color')]*(len(swarm_bars_order)+1) if swarm_bars_kwargs.get('color') is not None else ['black']*(len(swarm_bars_order)+1) if color_col is not None or is_paired else swarm_colors\n",
" swarm_bars_colors = [swarm_bars_kwargs.get('color')]*(len(swarm_bars_order)+1) if swarm_bars_kwargs.get('color') is not None else ['black']*(len(swarm_bars_order)+1) if color_col is not None or is_paired else swarm_colors\n",
" swarm_bars_kwargs.pop('color')\n",
" for swarm_bars_x,swarm_bars_y,c in zip(np.arange(0,len(swarm_bars_order)+1,1), swarm_means, swarm_bar_colors):\n",
" rawdata_axes.add_patch(mpatches.Rectangle((swarm_bars_x-0.2,0),\n",
" 0.5-0.1, swarm_bars_y, zorder=-1,color=c,**swarm_bars_kwargs))\n",
"\n",
" else:\n",
" pass\n",
" for swarm_bars_x,swarm_bars_y,c in zip(np.arange(0,len(swarm_bars_order)+1,1), swarm_means, swarm_bars_colors):\n",
" rawdata_axes.add_patch(mpatches.Rectangle((swarm_bars_x-0.25,0),\n",
" 0.5, swarm_bars_y, zorder=-1,color=c,**swarm_bars_kwargs))\n",
" \n",
" # Contrast Bars WIP\n",
" contrast_bars = plot_kwargs[\"contrast_bars\"]\n",
Expand All @@ -1695,21 +1695,58 @@
" for j, tick in enumerate(ticks_to_plot):\n",
" contrast_means.append(results.difference[j])\n",
"\n",
" contrast_bar_colors = [contrast_bars_kwargs.get('color')]*(len(ticks_to_plot)+1) if contrast_bars_kwargs.get('color') is not None else ['black']*(max(ticks_to_plot)+1) if color_col is not None or (proportional and is_paired) or is_paired else swarm_colors\n",
" contrast_bars_colors = [contrast_bars_kwargs.get('color')]*(len(ticks_to_plot)+1) if contrast_bars_kwargs.get('color') is not None else ['black']*(max(ticks_to_plot)+1) if color_col is not None or (proportional and is_paired) or is_paired else swarm_colors\n",
" contrast_bars_kwargs.pop('color')\n",
" for contrast_bars_x,contrast_bars_y in zip(ticks_to_plot, contrast_means):\n",
" contrast_axes.add_patch(mpatches.Rectangle((contrast_bars_x,0),0.25, contrast_bars_y, zorder=-1, color=contrast_bar_colors[contrast_bars_x], **contrast_bars_kwargs))\n",
" contrast_axes.add_patch(mpatches.Rectangle((contrast_bars_x-0.25,0),0.5, contrast_bars_y, zorder=-1, color=contrast_bars_colors[contrast_bars_x], **contrast_bars_kwargs))\n",
"\n",
" if show_mini_meta:\n",
" contrast_axes.add_patch(mpatches.Rectangle((max(rawdata_axes.get_xticks())+2,0),0.25, mini_meta_delta.difference, zorder=-1, color='black', **contrast_bars_kwargs))\n",
" contrast_axes.add_patch(mpatches.Rectangle((max(rawdata_axes.get_xticks())+2-0.25,0),0.5, mini_meta_delta.difference, zorder=-1, color='black', **contrast_bars_kwargs))\n",
"\n",
" if show_delta2:\n",
" contrast_axes.add_patch(mpatches.Rectangle((max(rawdata_axes.get_xticks())+2,0),0.25, delta_delta.difference, zorder=-1, color='black', **contrast_bars_kwargs))\n",
" contrast_axes.add_patch(mpatches.Rectangle((max(rawdata_axes.get_xticks())+2-0.25,0),0.5, delta_delta.difference, zorder=-1, color='black', **contrast_bars_kwargs))\n",
"\n",
" ################################################### Swarm & Contrast Bars WIP\n",
"\n",
" ################################################### Summary Bars WIP\n",
"\n",
" summary_bars = plot_kwargs[\"summary_bars\"]\n",
" default_summary_bars_kwargs = {\"color\": None, \"alpha\": 0.15}\n",
" if plot_kwargs[\"summary_bars_kwargs\"] is None:\n",
" summary_bars_kwargs = default_summary_bars_kwargs\n",
" else:\n",
" pass\n",
" \n",
" ################################################### Contrast Bars WIP\n",
" summary_bars_kwargs = merge_two_dicts(default_summary_bars_kwargs, plot_kwargs[\"summary_bars_kwargs\"])\n",
"\n",
" if summary_bars is not None:\n",
" if not isinstance(summary_bars, list):\n",
" raise TypeError(\"summary_bars must be a list of indices (ints).\")\n",
" if not all(isinstance(i, int) for i in summary_bars):\n",
" raise TypeError(\"summary_bars must be a list of indices (ints).\")\n",
" if any(i >= len(results) for i in summary_bars):\n",
" raise ValueError(\"Index {} chosen is out of range for the contrast objects.\".format([i for i in summary_bars if i >= len(results)]))\n",
" if float_contrast:\n",
" raise ValueError(\"summary_bars cannot be used with Gardner-Altman plots.\")\n",
" else:\n",
" print('Summary plots WIP')\n",
" summary_xmin, summary_xmax = contrast_axes.get_xlim()\n",
" summary_bars_colors = [summary_bars_kwargs.get('color')]*(len(summary_bars)+1) if summary_bars_kwargs.get('color') is not None else ['black']*(max(summary_bars)+1) if color_col is not None or (proportional and is_paired) or is_paired else swarm_colors\n",
" summary_bars_kwargs.pop('color')\n",
" for summary_index in summary_bars:\n",
" print('Summary plot for contrast object:', summary_index)\n",
" if ci_type == \"bca\":\n",
" summary_ci_low = results.bca_low[summary_index]\n",
" summary_ci_high = results.bca_high[summary_index]\n",
" else:\n",
" summary_ci_low = results.pct_low[summary_index]\n",
" summary_ci_high = results.pct_high[summary_index]\n",
"\n",
" summary_color = summary_bars_colors[ticks_to_plot[summary_index]]\n",
"\n",
" contrast_axes.add_patch(mpatches.Rectangle((summary_xmin,summary_ci_low),summary_xmax+1, \n",
" summary_ci_high-summary_ci_low, zorder=-2, color=summary_color, **summary_bars_kwargs))\n",
"\n",
"\n",
" ################################################### Summary Bars WIP\n",
"\n",
" # Make sure no stray ticks appear!\n",
" rawdata_axes.xaxis.set_ticks_position(\"bottom\")\n",
Expand Down

0 comments on commit cb28e6c

Please sign in to comment.