Skip to content

Add ASCII text plotting for LLM-friendly distribution comparisons#343

Closed
sahil350 wants to merge 1 commit intofacebookresearch:mainfrom
sahil350:export-D93754276
Closed

Add ASCII text plotting for LLM-friendly distribution comparisons#343
sahil350 wants to merge 1 commit intofacebookresearch:mainfrom
sahil350:export-D93754276

Conversation

@sahil350
Copy link
Contributor

Summary:
This change adds ASCII text plotting capabilities to the balance library, enabling text-based visualization of weighted distribution comparisons that is suitable for LLM consumption.

The motivation is to provide a way to visualize balance diagnostics in environments where graphical plotting is not available or practical, such as when working with LLMs that can process text output but not images.

Key additions:

  • New ascii_plots.py module with functions for ASCII histograms (ascii_plot_hist) and barplots (ascii_plot_bar)
  • ascii_plot_dist dispatcher that automatically chooses histogram vs barplot based on variable type
  • Integration into the existing plot_dist API via library="balance" parameter
  • Support for weighted distributions with multiple dataset comparisons using distinct characters (#, =, ., +, ~, *) for each dataset

Differential Revision: D93754276

@meta-cla meta-cla bot added the cla signed label Feb 20, 2026
@meta-codesync
Copy link

meta-codesync bot commented Feb 20, 2026

@sahil350 has exported this pull request. If you are a Meta employee, you can view the originating Diff in D93754276.

Copy link
Contributor

@talgalili talgalili left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review automatically exported from Phabricator review in Meta.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds ASCII text plotting capabilities to the balance library, enabling text-based visualization of weighted distribution comparisons. This is particularly useful for LLM consumption and terminal-based workflows where graphical plots are not available.

Changes:

  • New ascii_plots.py module with functions for creating ASCII histograms, barplots, and comparative histograms
  • Integration of ASCII plotting into the existing plot_dist API via library="balance" parameter
  • Support for weighted distributions with multiple dataset comparisons using distinct Unicode block characters

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
balance/stats_and_plots/ascii_plots.py New module implementing ASCII plotting functions (ascii_plot_hist, ascii_plot_bar, ascii_comparative_hist, ascii_plot_dist) with comprehensive docstrings
balance/stats_and_plots/weighted_comparisons_plots.py Updated plot_dist to support library="balance" option, added dist_type="hist_ascii" to type hints, improved error messages
balance/balancedf_class.py Updated plot() method documentation and return type to include ASCII output option
tests/test_ascii_plots.py Comprehensive test suite with unit tests for helpers, integration tests, and end-to-end tests with exact output verification
tests/test_weighted_comparisons_plots.py Updated error message assertion to match new, more concise error format
tutorials/balance_quickstart.ipynb Added examples demonstrating ASCII plotting functions, fixed Unicode character display

Comment on lines 1513 to 1523
elif library == "balance":
from balance.stats_and_plots.ascii_plots import ascii_plot_dist

return ascii_plot_dist(
dfs=dfs,
names=names,
variables=variables,
numeric_n_values_threshold=numeric_n_values_threshold,
weighted=weighted,
**kwargs,
)
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When library="balance", the dist_type parameter (if provided) is silently ignored since ascii_plot_dist doesn't accept or use it. Consider adding validation here to either:

  1. Raise an error if dist_type is not None, making it clear that dist_type is not applicable for the balance library
  2. Log a warning if dist_type is provided but will be ignored

This would prevent user confusion when they pass dist_type="hist_ascii" as suggested in the docstring example in balancedf_class.py but see no effect.

Copilot uses AI. Check for mistakes.
s3_null.covars().plot(dist_type = "qq")

# ASCII text output (suitable for LLM consumption):
s3_null.covars().plot(library = "balance", dist_type = "hist_ascii")
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The example shows passing dist_type="hist_ascii" when using library="balance", but the implementation does not validate or use the dist_type parameter for the balance library. The ascii_plot_dist function automatically chooses between histogram and barplot based on variable type and doesn't accept a dist_type parameter.

Either remove the dist_type="hist_ascii" from this example, or add validation in the plot_dist function to warn/error when dist_type is passed with library="balance" since it's ignored.

Suggested change
s3_null.covars().plot(library = "balance", dist_type = "hist_ascii")
s3_null.covars().plot(library = "balance")

Copilot uses AI. Check for mistakes.
Comment on lines 1396 to 1397
dist_type (Literal["kde", "hist", "qq", "ecdf", "hist_ascii"], optional): The type of plot to draw. The 'qq' and 'kde' options are available for library="plotly",
while all options except hist_ascii are available if using library="seaborn". The 'hist_ascii' option is used with library="balance". Defaults to "kde".
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation states that hist_ascii is a valid dist_type option used with library="balance", but the implementation doesn't validate or use this parameter when library="balance". The ascii_plot_dist function automatically dispatches to histogram or barplot based on variable type and doesn't accept a dist_type parameter.

Consider either:

  1. Removing hist_ascii from the type hint and documentation, clarifying that dist_type is not applicable for library="balance"
  2. Adding validation to raise an error if dist_type is provided when library="balance" to avoid silent parameter ignoring
  3. Passing dist_type through **kwargs if it will be silently ignored anyway, but documenting this clearly

Copilot uses AI. Check for mistakes.
sahil350 added a commit to sahil350/balance that referenced this pull request Feb 20, 2026
…cebookresearch#343)

Summary:

This change adds ASCII text plotting capabilities to the balance library, enabling text-based visualization of weighted distribution comparisons that is suitable for LLM consumption.

The motivation is to provide a way to visualize balance diagnostics in environments where graphical plotting is not available or practical, such as when working with LLMs that can process text output but not images.

Key additions:
- New `ascii_plots.py` module with functions for ASCII histograms (`ascii_plot_hist`) and barplots (`ascii_plot_bar`)
- `ascii_plot_dist` dispatcher that automatically chooses histogram vs barplot based on variable type
- Integration into the existing `plot_dist` API via `library="balance"` parameter
- Support for weighted distributions with multiple dataset comparisons using distinct characters (#, =, ., +, ~, *) for each dataset

Differential Revision: D93754276
@talgalili talgalili requested a review from Copilot February 20, 2026 18:17
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Comment on lines +1397 to +1400
while all options except hist_ascii are available if using library="seaborn". The 'hist_ascii' option is used with library="balance";
it is the only dist_type supported when library="balance". Defaults to "kde".
library (Literal["plotly", "seaborn", "balance"], optional): Whichever library to use for the plot.
Use "balance" for ASCII text output suitable for LLM consumption (only dist_type="hist_ascii" is supported). Defaults to "plotly".
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Misleading documentation regarding dist_type for library="balance". The docstring states that dist_type="hist_ascii" is the only option supported with library="balance" and even includes it in the Literal type hint. However, the actual implementation in ascii_plot_dist() does not accept or use a dist_type parameter at all - it automatically dispatches to ascii_plot_bar for categorical variables and ascii_plot_hist for numeric variables. Either: (1) update the documentation to clarify that dist_type is ignored for library="balance" and the plot type is automatically chosen, or (2) accept and validate dist_type="hist_ascii" for consistency with the documented API.

Suggested change
while all options except hist_ascii are available if using library="seaborn". The 'hist_ascii' option is used with library="balance";
it is the only dist_type supported when library="balance". Defaults to "kde".
library (Literal["plotly", "seaborn", "balance"], optional): Whichever library to use for the plot.
Use "balance" for ASCII text output suitable for LLM consumption (only dist_type="hist_ascii" is supported). Defaults to "plotly".
while all options except "hist_ascii" are available if using library="seaborn". For library="balance", this argument is ignored and kept
only for API compatibility; the function automatically selects an ASCII histogram or bar plot based on the variable type. Defaults to "kde".
library (Literal["plotly", "seaborn", "balance"], optional): Whichever library to use for the plot.
Use "balance" for ASCII text output suitable for LLM consumption; for this library, ``dist_type`` is ignored and the ASCII plot type is chosen automatically.

Copilot uses AI. Check for mistakes.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still valuable to keep hist_ascii, as it let's the end user know what type of dist is produced.

Comment on lines 1514 to 1524
elif library == "balance":
from balance.stats_and_plots.ascii_plots import ascii_plot_dist

return ascii_plot_dist(
dfs=dfs,
names=names,
variables=variables,
numeric_n_values_threshold=numeric_n_values_threshold,
weighted=weighted,
**kwargs,
)
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing CHANGELOG.md entry for this user-visible feature addition. According to the coding guidelines (section 6), user-visible fixes and features MUST include an entry in CHANGELOG.md. This PR adds a significant new feature (ASCII plotting with library="balance") that users will interact with, so it should be documented in the changelog.

Copilot generated this review using guidance from repository custom instructions.
sahil350 added a commit to sahil350/balance that referenced this pull request Feb 20, 2026
…cebookresearch#343)

Summary:

This change adds ASCII text plotting capabilities to the balance library, enabling text-based visualization of weighted distribution comparisons that is suitable for LLM consumption.

The motivation is to provide a way to visualize balance diagnostics in environments where graphical plotting is not available or practical, such as when working with LLMs that can process text output but not images.

Key additions:
- New `ascii_plots.py` module with functions for ASCII histograms (`ascii_plot_hist`) and barplots (`ascii_plot_bar`)
- `ascii_plot_dist` dispatcher that automatically chooses histogram vs barplot based on variable type
- Integration into the existing `plot_dist` API via `library="balance"` parameter
- Support for weighted distributions with multiple dataset comparisons using distinct characters (#, =, ., +, ~, *) for each dataset

Differential Revision: D93754276
@talgalili talgalili requested a review from Copilot February 20, 2026 20:47
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.

Comment on lines +25 to +28
# Characters used to distinguish datasets in ASCII bars.
# Each dataset gets a unique character from this list.
BAR_CHARS: List[str] = ["█", "▒", "▐", "░", "▄", "▀"]

Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description says dataset comparison characters are (#, =, ., +, ~, *), but the implementation uses Unicode block characters in BAR_CHARS (e.g., , , , …). Either update the PR description to match the implementation, or change BAR_CHARS to the documented characters so consumers aren’t surprised by non-ASCII output.

Copilot uses AI. Check for mistakes.
Comment on lines 30 to 52
def _weighted_histogram(
values: pd.Series,
weights: Optional[pd.Series],
bin_edges: npt.NDArray[np.floating],
) -> npt.NDArray[np.floating]:
"""Computes a weighted histogram and normalizes counts to proportions.

Args:
values: The numeric data values.
weights: Optional weights. If None, uniform weights are used.
bin_edges: Pre-computed bin edges (length n_bins + 1).

Returns:
Array of proportions for each bin (sums to 1.0, or all zeros if empty).
"""
weights_arr: Optional[npt.NDArray[np.floating]] = None
if weights is not None:
weights_arr = np.asarray(weights, dtype=float)
counts, _ = np.histogram(values, bins=bin_edges, weights=weights_arr)
total = counts.sum()
if total > 0:
return counts / total
return np.zeros_like(counts, dtype=float)
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

_weighted_histogram() accepts weights but never validates them (e.g., non-numeric or negative values). Other weighted utilities in this codebase use _check_weights_are_valid(); without similar validation here, negative weights can produce incorrect or all-zero histograms with no clear error. Consider calling _check_weights_are_valid(weights) (after dropping NA/inf) before computing the histogram, and raising an actionable error when weights are invalid.

Copilot uses AI. Check for mistakes.
Comment on lines 686 to 715
"source": "## ASCII Comparative Histogram\n\nWhen working in a terminal, notebook with limited rendering, or logging context, you can use `ascii_comparative_hist` to get a quick text-based comparison of numeric distributions across datasets.\n\nThe first dataset serves as the **baseline**. For each bin in subsequent datasets:\n- `█` (solid) shows the proportion shared with the baseline\n- `▒` (shaded) shows excess beyond the baseline\n- ` ]` (right bracket) shows deficit relative to the baseline",
"metadata": {}
},
{
"cell_type": "code",
"source": "from balance.stats_and_plots.ascii_plots import ascii_comparative_hist\n\n# Compare the income distribution: target (baseline) vs unadjusted sample\ndfs = [\n {\"df\": target_df, \"weight\": None},\n {\"df\": sample_df, \"weight\": None},\n]\nprint(ascii_comparative_hist(dfs, names=[\"Target\", \"Sample\"], column=\"income\", n_bins=5, bar_width=20))",
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": "## ASCII Grouped Histogram\n\n`ascii_plot_hist` provides a simpler side-by-side view: each dataset gets its own bar (with a distinct fill character) so you can compare how mass is distributed across bins. Bar lengths are proportional to weighted frequency within each dataset.",
"metadata": {}
},
{
"cell_type": "code",
"source": "from balance.stats_and_plots.ascii_plots import ascii_plot_hist\n\n# Compare the income distribution: target vs unadjusted sample\ndfs = [\n {\"df\": target_df, \"weight\": None},\n {\"df\": sample_df, \"weight\": None},\n]\nprint(ascii_plot_hist(dfs, names=[\"Target\", \"Sample\"], column=\"income\", n_bins=5, bar_width=30))",
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": "## ASCII Plot: Adjusted vs Unadjusted vs Target\n\nYou can also use `library=\"balance\"` with the standard `.covars().plot()` API on an\nadjusted `Sample` to get a three-way ASCII comparison. This shows the full pipeline\noutput — unadjusted sample, adjusted (IPW-reweighted) sample, and target population —\nside by side, which is useful for verifying that adjustment moved the distributions\nin the right direction.\n\nEach variable is plotted as a grouped barplot (categorical) or histogram (numeric).\nThe three fill characters distinguish the datasets:\n- `█` = **sample** (unadjusted)\n- `▒` = **adjusted** (after IPW)\n- `▐` = **population** (target)",
"metadata": {}
},
{
"cell_type": "code",
"source": "# ASCII plot comparing all three: unadjusted sample, adjusted sample, and target population\nadjusted.covars().plot(library=\"balance\", bar_width=30)",
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The newly added notebook cells use "source" as a single multiline string, while the rest of the notebook uses the standard nbformat list-of-strings form. This inconsistency can break tooling that expects normalized notebooks (formatters, nbformat validation, some diffs). Consider re-saving/normalizing the notebook so each cell’s source is a list of strings, consistent with the existing cells.

Suggested change
"source": "## ASCII Comparative Histogram\n\nWhen working in a terminal, notebook with limited rendering, or logging context, you can use `ascii_comparative_hist` to get a quick text-based comparison of numeric distributions across datasets.\n\nThe first dataset serves as the **baseline**. For each bin in subsequent datasets:\n- `█` (solid) shows the proportion shared with the baseline\n- `▒` (shaded) shows excess beyond the baseline\n- ` ]` (right bracket) shows deficit relative to the baseline",
"metadata": {}
},
{
"cell_type": "code",
"source": "from balance.stats_and_plots.ascii_plots import ascii_comparative_hist\n\n# Compare the income distribution: target (baseline) vs unadjusted sample\ndfs = [\n {\"df\": target_df, \"weight\": None},\n {\"df\": sample_df, \"weight\": None},\n]\nprint(ascii_comparative_hist(dfs, names=[\"Target\", \"Sample\"], column=\"income\", n_bins=5, bar_width=20))",
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": "## ASCII Grouped Histogram\n\n`ascii_plot_hist` provides a simpler side-by-side view: each dataset gets its own bar (with a distinct fill character) so you can compare how mass is distributed across bins. Bar lengths are proportional to weighted frequency within each dataset.",
"metadata": {}
},
{
"cell_type": "code",
"source": "from balance.stats_and_plots.ascii_plots import ascii_plot_hist\n\n# Compare the income distribution: target vs unadjusted sample\ndfs = [\n {\"df\": target_df, \"weight\": None},\n {\"df\": sample_df, \"weight\": None},\n]\nprint(ascii_plot_hist(dfs, names=[\"Target\", \"Sample\"], column=\"income\", n_bins=5, bar_width=30))",
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": "## ASCII Plot: Adjusted vs Unadjusted vs Target\n\nYou can also use `library=\"balance\"` with the standard `.covars().plot()` API on an\nadjusted `Sample` to get a three-way ASCII comparison. This shows the full pipeline\noutput — unadjusted sample, adjusted (IPW-reweighted) sample, and target population —\nside by side, which is useful for verifying that adjustment moved the distributions\nin the right direction.\n\nEach variable is plotted as a grouped barplot (categorical) or histogram (numeric).\nThe three fill characters distinguish the datasets:\n- `█` = **sample** (unadjusted)\n- `▒` = **adjusted** (after IPW)\n- `▐` = **population** (target)",
"metadata": {}
},
{
"cell_type": "code",
"source": "# ASCII plot comparing all three: unadjusted sample, adjusted sample, and target population\nadjusted.covars().plot(library=\"balance\", bar_width=30)",
"source": [
"## ASCII Comparative Histogram\n",
"\n",
"When working in a terminal, notebook with limited rendering, or logging context, you can use `ascii_comparative_hist` to get a quick text-based comparison of numeric distributions across datasets.\n",
"\n",
"The first dataset serves as the **baseline**. For each bin in subsequent datasets:\n",
"- `█` (solid) shows the proportion shared with the baseline\n",
"- `▒` (shaded) shows excess beyond the baseline\n",
"- ` ]` (right bracket) shows deficit relative to the baseline"
],
"metadata": {}
},
{
"cell_type": "code",
"source": [
"from balance.stats_and_plots.ascii_plots import ascii_comparative_hist\n",
"\n",
"# Compare the income distribution: target (baseline) vs unadjusted sample\n",
"dfs = [\n",
" {\"df\": target_df, \"weight\": None},\n",
" {\"df\": sample_df, \"weight\": None},\n",
"]\n",
"print(ascii_comparative_hist(dfs, names=[\"Target\", \"Sample\"], column=\"income\", n_bins=5, bar_width=20))"
],
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## ASCII Grouped Histogram\n",
"\n",
"`ascii_plot_hist` provides a simpler side-by-side view: each dataset gets its own bar (with a distinct fill character) so you can compare how mass is distributed across bins. Bar lengths are proportional to weighted frequency within each dataset."
],
"metadata": {}
},
{
"cell_type": "code",
"source": [
"from balance.stats_and_plots.ascii_plots import ascii_plot_hist\n",
"\n",
"# Compare the income distribution: target vs unadjusted sample\n",
"dfs = [\n",
" {\"df\": target_df, \"weight\": None},\n",
" {\"df\": sample_df, \"weight\": None},\n",
"]\n",
"print(ascii_plot_hist(dfs, names=[\"Target\", \"Sample\"], column=\"income\", n_bins=5, bar_width=30))"
],
"metadata": {},
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"source": [
"## ASCII Plot: Adjusted vs Unadjusted vs Target\n",
"\n",
"You can also use `library=\"balance\"` with the standard `.covars().plot()` API on an\n",
"adjusted `Sample` to get a three-way ASCII comparison. This shows the full pipeline\n",
"output — unadjusted sample, adjusted (IPW-reweighted) sample, and target population —\n",
"side by side, which is useful for verifying that adjustment moved the distributions\n",
"in the right direction.\n",
"\n",
"Each variable is plotted as a grouped barplot (categorical) or histogram (numeric).\n",
"The three fill characters distinguish the datasets:\n",
"- `█` = **sample** (unadjusted)\n",
"- `▒` = **adjusted** (after IPW)\n",
"- `▐` = **population** (target)"
],
"metadata": {}
},
{
"cell_type": "code",
"source": [
"# ASCII plot comparing all three: unadjusted sample, adjusted sample, and target population\n",
"adjusted.covars().plot(library=\"balance\", bar_width=30)"
],

Copilot uses AI. Check for mistakes.
weighted: bool = True,
dist_type: Optional[Literal["kde", "hist", "qq", "ecdf"]] = None,
library: Literal["plotly", "seaborn"] = "plotly",
dist_type: Optional[Literal["kde", "hist", "qq", "ecdf", "hist_ascii"]] = None,
Copy link

Copilot AI Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dist_type now includes "hist_ascii" in its type hint, but the library="plotly" branch doesn’t explicitly handle/reject it. As a result, plot_dist(..., library="plotly", dist_type="hist_ascii") will silently fall back to the default plotly behavior (treated like None), which is confusing given the docstring states hist_ascii is only supported for library="balance". Consider adding explicit validation (raise ValueError) for hist_ascii when library is "plotly" (and possibly mention it in the plotly error message).

Suggested change
dist_type: Optional[Literal["kde", "hist", "qq", "ecdf", "hist_ascii"]] = None,
dist_type: Optional[Literal["kde", "hist", "qq", "ecdf"]] = None,

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@talgalili talgalili left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review automatically exported from Phabricator review in Meta.

sahil350 added a commit to sahil350/balance that referenced this pull request Feb 20, 2026
…cebookresearch#343)

Summary:

This change adds ASCII text plotting capabilities to the balance library, enabling text-based visualization of weighted distribution comparisons that is suitable for LLM consumption.

The motivation is to provide a way to visualize balance diagnostics in environments where graphical plotting is not available or practical, such as when working with LLMs that can process text output but not images.

Key additions:
- New `ascii_plots.py` module with functions for ASCII histograms (`ascii_plot_hist`) and barplots (`ascii_plot_bar`)
- `ascii_plot_dist` dispatcher that automatically chooses histogram vs barplot based on variable type
- Integration into the existing `plot_dist` API via `library="balance"` parameter
- Support for weighted distributions with multiple dataset comparisons using distinct characters (`█`, `▒`, `▐`, `░`) for each dataset

Reviewed By: talgalili

Differential Revision: D93754276
sahil350 added a commit to sahil350/balance that referenced this pull request Feb 20, 2026
…cebookresearch#343)

Summary:

This change adds ASCII text plotting capabilities to the balance library, enabling text-based visualization of weighted distribution comparisons that is suitable for LLM consumption.

The motivation is to provide a way to visualize balance diagnostics in environments where graphical plotting is not available or practical, such as when working with LLMs that can process text output but not images.

Key additions:
- New `ascii_plots.py` module with functions for ASCII histograms (`ascii_plot_hist`) and barplots (`ascii_plot_bar`)
- `ascii_plot_dist` dispatcher that automatically chooses histogram vs barplot based on variable type
- Integration into the existing `plot_dist` API via `library="balance"` parameter
- Support for weighted distributions with multiple dataset comparisons using distinct characters (`█`, `▒`, `▐`, `░`) for each dataset

Reviewed By: talgalili

Differential Revision: D93754276
sahil350 added a commit to sahil350/balance that referenced this pull request Feb 21, 2026
…cebookresearch#343)

Summary:

This change adds ASCII text plotting capabilities to the balance library, enabling text-based visualization of weighted distribution comparisons that is suitable for LLM consumption.

The motivation is to provide a way to visualize balance diagnostics in environments where graphical plotting is not available or practical, such as when working with LLMs that can process text output but not images.

Key additions:
- New `ascii_plots.py` module with functions for ASCII histograms (`ascii_plot_hist`) and barplots (`ascii_plot_bar`)
- `ascii_plot_dist` dispatcher that automatically chooses histogram vs barplot based on variable type
- Integration into the existing `plot_dist` API via `library="balance"` parameter
- Support for weighted distributions with multiple dataset comparisons using distinct characters (`█`, `▒`, `▐`, `░`) for each dataset

Reviewed By: talgalili

Differential Revision: D93754276
…cebookresearch#343)

Summary:

This change adds ASCII text plotting capabilities to the balance library, enabling text-based visualization of weighted distribution comparisons that is suitable for LLM consumption.

The motivation is to provide a way to visualize balance diagnostics in environments where graphical plotting is not available or practical, such as when working with LLMs that can process text output but not images.

Key additions:
- New `ascii_plots.py` module with functions for ASCII histograms (`ascii_plot_hist`) and barplots (`ascii_plot_bar`)
- `ascii_plot_dist` dispatcher that automatically chooses histogram vs barplot based on variable type
- Integration into the existing `plot_dist` API via `library="balance"` parameter
- Support for weighted distributions with multiple dataset comparisons using distinct characters (`█`, `▒`, `▐`, `░`) for each dataset

Reviewed By: talgalili

Differential Revision: D93754276
@meta-codesync
Copy link

meta-codesync bot commented Feb 21, 2026

This pull request has been merged in c33a01c.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants