qdiv.plot.harvey_balls

qdiv.plot.harvey_balls(meta, columns_by=None, *, rows_by='index', row_colors=None, column_colors=None, row_label_width=4, figsize=(7.086614173228346, 5.511811023622047), fontsize=10, savename=None)[source]

Plot Harvey balls (fraction-of-circle indicators) for percentage columns in metadata.

Parameters:
  • meta (DataFrame | MicrobiomeData-like | dict) – Object with metadata table. Must contain the columns_by fields and optionally a rows_by field used to derive row labels.

  • columns_by (list of str) – List of metadata column names containing percentages (0–100) to visualize as Harvey balls across rows.

  • rows_by (str, default='index') – Name of the metadata column used as row labels. If ‘index’, the DataFrame index is used as row labels.

  • row_colors (str, optional) – Name of metadata column containing per-row text colors (e.g., ‘red’, ‘#333’). If None, all row labels are drawn in black.

  • column_colors (list of str, optional) – Colors for the column headers (one per columns_by). If None, defaults to black for all headers; if provided but shorter than columns_by, the list is padded with black.

  • row_label_width (int, default=4) – Number of GridSpec columns reserved for the row label area (left-hand text).

  • figsize (tuple of float, default=(18/2.54, 14/2.54)) – Figure size in inches.

  • fontsize (int, default=10) – Base font size for the figure.

  • savename (str, optional) – If provided, saves the figure (PNG) to this path and also as PDF (savename + ‘.pdf’).

Returns:

  • fig (matplotlib.figure.Figure)

  • plot_data (pandas.DataFrame) – A DataFrame containing the row labels and selected percentage values used for plotting: columns [‘__label__’, *columns_by]. Returns None if validation fails.

Return type:

Tuple[plt.figure.Figure, pd.DataFrame]

Notes

  • Harvey balls are drawn using pie charts where the black wedge represents the percentage, and the white wedge represents the complement to 100%.

  • All values in columns_by must be numeric (0–100). Non-numeric rows are coerced if possible; rows with missing values will still be plotted (missing values treated as 0).

  • If rows_by=’index’, row labels are taken from meta.index; otherwise, from meta[rows_by].

Examples

>>> df = harvey_balls(
...     meta,
...     rows_by='Treatment',
...     columns_by=['PFAS_%', 'DOC_%'],
...     row_colors='TreatmentColor',
...     column_colors=['#1f77b4', '#ff7f0e'],
...     savename='harvey_balls'
... )
>>> print(df.head())