Skip to content

Commit

Permalink
Fixed coloring of summary bars and added delta text (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
JAnns98 committed Aug 29, 2024
1 parent d4d62cf commit 641c4ed
Show file tree
Hide file tree
Showing 6 changed files with 139 additions and 17 deletions.
10 changes: 10 additions & 0 deletions dabest/_effsize_objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -1024,6 +1024,8 @@ def plot(
swarm_bars_kwargs=None,
summary_bars=None,
summary_bars_kwargs=None,
delta_text=True,
delta_text_kwargs=None,
):
"""
Creates an estimation plot for the effect size of interest.
Expand Down Expand Up @@ -1186,6 +1188,14 @@ def 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}
delta_text : boolean, default True
Whether or not to display the text deltas.
delta_text_kwargs : dict, default None
Pass relevant keyword arguments to the delta text. Pass any keyword arguments accepted by
matplotlib.text.Text here, as a string. If None, the following keywords are passed:
{"color": None, "alpha": 1, "fontsize": 10, "ha": 'center', "va": 'center', "rotation": 0,
"x_location": 'right', "x_coordinates": None, "y_coordinates": None}
Use "x_coordinates" and "y_coordinates" if you would like to specify the text locations manually.
Returns
-------
Expand Down
6 changes: 3 additions & 3 deletions dabest/plot_tools.py
Original file line number Diff line number Diff line change
Expand Up @@ -824,7 +824,7 @@ def summary_bars_plotter(summary_bars: list, results: object, ax_to_plot: object
# End checks
else:
summary_xmin, summary_xmax = ax_to_plot.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_colors = [summary_bars_kwargs.get('color')]*(max(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:
if ci_type == "bca":
Expand Down Expand Up @@ -880,7 +880,7 @@ def contrast_bars_plotter(results: object, ax_to_plot: object, swarm_plot_ax: o
for j, tick in enumerate(ticks_to_plot):
contrast_means.append(results.difference[j])

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_colors = [contrast_bars_kwargs.get('color')]*(max(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):
ax_to_plot.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))
Expand Down Expand Up @@ -929,7 +929,7 @@ def swarm_bars_plotter(plot_data: object, xvar: str, yvar: str, ax: object,
swarm_bars_order = pd.unique(plot_data[xvar])

swarm_means = plot_data.groupby(xvar)[yvar].mean().reindex(index=swarm_bars_order)
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_colors = [swarm_bars_kwargs.get('color')]*(max(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_bars_colors):
ax.add_patch(mpatches.Rectangle((swarm_bars_x-0.25,0),
Expand Down
57 changes: 56 additions & 1 deletion dabest/plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ def effectsize_df_plotter(effectsize_df, **plot_kwargs):
fontsize_delta2label=12,
swarm_bars=True, swarm_bars_kwargs=None,
contrast_bars=True, contrast_bars_kwargs=None,
delta_text=True, delta_text_kwargs=None,
"""
from .misc_tools import merge_two_dicts
from .plot_tools import (
Expand Down Expand Up @@ -1637,6 +1637,61 @@ def effectsize_df_plotter(effectsize_df, **plot_kwargs):

################################################### Swarm & Contrast & Summary Bars WIP END

################################################### Delta numbers WIP START
delta_text = plot_kwargs["delta_text"]
if delta_text:
default_delta_text_kwargs = {"color": None, "alpha": 1, "fontsize": 10, "ha": 'center', "va": 'center', "rotation": 0, "x_location": 'right', "x_coordinates": None, "y_coordinates": None}
if plot_kwargs["delta_text_kwargs"] is None:
delta_text_kwargs = default_delta_text_kwargs
else:
delta_text_kwargs = merge_two_dicts(default_delta_text_kwargs, plot_kwargs["delta_text_kwargs"])

delta_text_x_location = delta_text_kwargs.get('x_location')
if delta_text_x_location != 'right' and delta_text_x_location != 'left':
raise ValueError("delta_text_kwargs['x_location'] must be either 'right' or 'left'.")
delta_text_kwargs.pop('x_location')

delta_text_colors = [delta_text_kwargs.get('color')]*(max(ticks_to_plot)+1) if delta_text_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
delta_text_kwargs.pop('color')

Delta_Values = []
for j, tick in enumerate(ticks_to_plot):
Delta_Values.append(results.difference[j])

delta_text_x_coordinates = delta_text_kwargs.get('x_coordinates')
delta_text_y_coordinates = delta_text_kwargs.get('y_coordinates')

if delta_text_x_coordinates is not None:
if not isinstance(delta_text_x_coordinates, list):
raise TypeError("delta_text_kwargs['x_coordinates'] must be a list of x-coordinates.")
if len(delta_text_x_coordinates) != len(ticks_to_plot):
raise ValueError("delta_text_kwargs['x_coordinates'] must have the same length as the number of ticks to plot.")
delta_text_x_coordinates_default = False
delta_text_kwargs.pop('x_coordinates')
else:
delta_text_x_coordinates = ticks_to_plot
delta_text_x_coordinates_default = True
delta_text_kwargs.pop('x_coordinates')


if delta_text_y_coordinates is not None:
if not isinstance(delta_text_y_coordinates, list):
raise TypeError("delta_text_kwargs['y_coordinates'] must be a list of y-coordinates.")
if len(delta_text_y_coordinates) != len(ticks_to_plot):
raise ValueError("delta_text_kwargs['y_coordinates'] must have the same length as the number of ticks to plot.")
delta_text_kwargs.pop('y_coordinates')
else:
delta_text_y_coordinates = Delta_Values
delta_text_kwargs.pop('y_coordinates')

for x,y,t,tick in zip(delta_text_x_coordinates, delta_text_y_coordinates,Delta_Values,ticks_to_plot):
Delta_Text = '+'+'{0:.2f}'.format(t) if t > 0 else '{0:.2f}'.format(t)
X_Adjust = 0 if not delta_text_x_coordinates_default else 0.53 if delta_text_x_location == 'right' else -0.35
contrast_axes.text(x+X_Adjust, y, Delta_Text, color=delta_text_colors[tick],**delta_text_kwargs)

################################################### Delta numbers WIP END


# Make sure no stray ticks appear!
rawdata_axes.xaxis.set_ticks_position("bottom")
rawdata_axes.yaxis.set_ticks_position("left")
Expand Down
16 changes: 11 additions & 5 deletions nbs/API/effsize_objects.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,8 @@
" swarm_bars_kwargs=None,\n",
" summary_bars=None,\n",
" summary_bars_kwargs=None,\n",
" delta_text=True,\n",
" delta_text_kwargs=None,\n",
" ):\n",
" \"\"\"\n",
" Creates an estimation plot for the effect size of interest.\n",
Expand Down Expand Up @@ -1347,6 +1349,14 @@
" 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",
" delta_text : boolean, default True\n",
" Whether or not to display the text deltas.\n",
" delta_text_kwargs : dict, default None\n",
" Pass relevant keyword arguments to the delta text. Pass any keyword arguments accepted by\n",
" matplotlib.text.Text here, as a string. If None, the following keywords are passed:\n",
" {\"color\": None, \"alpha\": 1, \"fontsize\": 10, \"ha\": 'center', \"va\": 'center', \"rotation\": 0, \n",
" \"x_location\": 'right', \"x_coordinates\": None, \"y_coordinates\": None}\n",
" Use \"x_coordinates\" and \"y_coordinates\" if you would like to specify the text locations manually.\n",
"\n",
" Returns\n",
" -------\n",
Expand Down Expand Up @@ -1949,13 +1959,9 @@
],
"metadata": {
"kernelspec": {
"display_name": "DABESTDEV",
"display_name": "python3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down
6 changes: 3 additions & 3 deletions nbs/API/plot_tools.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -878,7 +878,7 @@
"# End checks\n",
" else:\n",
" summary_xmin, summary_xmax = ax_to_plot.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_colors = [summary_bars_kwargs.get('color')]*(max(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",
" if ci_type == \"bca\":\n",
Expand Down Expand Up @@ -934,7 +934,7 @@
" for j, tick in enumerate(ticks_to_plot):\n",
" contrast_means.append(results.difference[j])\n",
"\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_colors = [contrast_bars_kwargs.get('color')]*(max(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",
" ax_to_plot.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",
Expand Down Expand Up @@ -983,7 +983,7 @@
" 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_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_colors = [swarm_bars_kwargs.get('color')]*(max(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_bars_colors):\n",
" ax.add_patch(mpatches.Rectangle((swarm_bars_x-0.25,0),\n",
Expand Down
61 changes: 56 additions & 5 deletions nbs/API/plotter.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@
" fontsize_delta2label=12,\n",
" swarm_bars=True, swarm_bars_kwargs=None,\n",
" contrast_bars=True, contrast_bars_kwargs=None,\n",
"\n",
" delta_text=True, delta_text_kwargs=None,\n",
" \"\"\"\n",
" from .misc_tools import merge_two_dicts\n",
" from .plot_tools import (\n",
Expand Down Expand Up @@ -1696,6 +1696,61 @@
" \n",
" ################################################### Swarm & Contrast & Summary Bars WIP END\n",
"\n",
" ################################################### Delta numbers WIP START\n",
" delta_text = plot_kwargs[\"delta_text\"]\n",
" if delta_text:\n",
" default_delta_text_kwargs = {\"color\": None, \"alpha\": 1, \"fontsize\": 10, \"ha\": 'center', \"va\": 'center', \"rotation\": 0, \"x_location\": 'right', \"x_coordinates\": None, \"y_coordinates\": None}\n",
" if plot_kwargs[\"delta_text_kwargs\"] is None:\n",
" delta_text_kwargs = default_delta_text_kwargs\n",
" else:\n",
" delta_text_kwargs = merge_two_dicts(default_delta_text_kwargs, plot_kwargs[\"delta_text_kwargs\"])\n",
"\n",
" delta_text_x_location = delta_text_kwargs.get('x_location')\n",
" if delta_text_x_location != 'right' and delta_text_x_location != 'left':\n",
" raise ValueError(\"delta_text_kwargs['x_location'] must be either 'right' or 'left'.\")\n",
" delta_text_kwargs.pop('x_location')\n",
"\n",
" delta_text_colors = [delta_text_kwargs.get('color')]*(max(ticks_to_plot)+1) if delta_text_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",
" delta_text_kwargs.pop('color')\n",
"\n",
" Delta_Values = []\n",
" for j, tick in enumerate(ticks_to_plot):\n",
" Delta_Values.append(results.difference[j])\n",
"\n",
" delta_text_x_coordinates = delta_text_kwargs.get('x_coordinates')\n",
" delta_text_y_coordinates = delta_text_kwargs.get('y_coordinates')\n",
"\n",
" if delta_text_x_coordinates is not None:\n",
" if not isinstance(delta_text_x_coordinates, list):\n",
" raise TypeError(\"delta_text_kwargs['x_coordinates'] must be a list of x-coordinates.\")\n",
" if len(delta_text_x_coordinates) != len(ticks_to_plot):\n",
" raise ValueError(\"delta_text_kwargs['x_coordinates'] must have the same length as the number of ticks to plot.\")\n",
" delta_text_x_coordinates_default = False\n",
" delta_text_kwargs.pop('x_coordinates')\n",
" else:\n",
" delta_text_x_coordinates = ticks_to_plot\n",
" delta_text_x_coordinates_default = True\n",
" delta_text_kwargs.pop('x_coordinates')\n",
"\n",
"\n",
" if delta_text_y_coordinates is not None:\n",
" if not isinstance(delta_text_y_coordinates, list):\n",
" raise TypeError(\"delta_text_kwargs['y_coordinates'] must be a list of y-coordinates.\")\n",
" if len(delta_text_y_coordinates) != len(ticks_to_plot):\n",
" raise ValueError(\"delta_text_kwargs['y_coordinates'] must have the same length as the number of ticks to plot.\")\n",
" delta_text_kwargs.pop('y_coordinates')\n",
" else:\n",
" delta_text_y_coordinates = Delta_Values\n",
" delta_text_kwargs.pop('y_coordinates')\n",
"\n",
" for x,y,t,tick in zip(delta_text_x_coordinates, delta_text_y_coordinates,Delta_Values,ticks_to_plot):\n",
" Delta_Text = '+'+'{0:.2f}'.format(t) if t > 0 else '{0:.2f}'.format(t)\n",
" X_Adjust = 0 if not delta_text_x_coordinates_default else 0.53 if delta_text_x_location == 'right' else -0.35\n",
" contrast_axes.text(x+X_Adjust, y, Delta_Text, color=delta_text_colors[tick],**delta_text_kwargs)\n",
"\n",
" ################################################### Delta numbers WIP END\n",
"\n",
"\n",
" # Make sure no stray ticks appear!\n",
" rawdata_axes.xaxis.set_ticks_position(\"bottom\")\n",
" rawdata_axes.yaxis.set_ticks_position(\"left\")\n",
Expand All @@ -1717,10 +1772,6 @@
"display_name": "python3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.11.8"
}
},
"nbformat": 4,
Expand Down

0 comments on commit 641c4ed

Please sign in to comment.