hmbp 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,37 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ workflow_dispatch:
9
+
10
+ jobs:
11
+ publish:
12
+ runs-on: ubuntu-latest
13
+ permissions:
14
+ id-token: write # Required for trusted publishing
15
+
16
+ steps:
17
+ - uses: actions/checkout@v4
18
+ with:
19
+ fetch-depth: 0 # Full history for setuptools-scm versioning
20
+
21
+ - uses: actions/setup-python@v5
22
+ with:
23
+ python-version: '3.11'
24
+
25
+ - name: Install build tools
26
+ run: pip install build
27
+
28
+ - name: Build package
29
+ run: python -m build
30
+
31
+ - name: List artifacts
32
+ run: ls -la dist/
33
+
34
+ - name: Publish to PyPI
35
+ uses: pypa/gh-action-pypi-publish@release/v1
36
+ # Uses trusted publishing - no API token needed
37
+ # Configure at: https://pypi.org/manage/account/publishing/
hmbp-0.2.1/.gitignore ADDED
@@ -0,0 +1,46 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ *.egg-info/
20
+ .installed.cfg
21
+ *.egg
22
+
23
+ # Virtual environments
24
+ .venv/
25
+ venv/
26
+ ENV/
27
+
28
+ # IDE
29
+ .idea/
30
+ .vscode/
31
+ *.swp
32
+ *.swo
33
+
34
+ # Testing
35
+ .pytest_cache/
36
+ .coverage
37
+ htmlcov/
38
+
39
+ # OS
40
+ .DS_Store
41
+ Thumbs.db
42
+
43
+ # Project specific
44
+ figures/
45
+ .claude/
46
+ hmbp/_version.py
hmbp-0.2.1/PKG-INFO ADDED
@@ -0,0 +1,129 @@
1
+ Metadata-Version: 2.4
2
+ Name: hmbp
3
+ Version: 0.2.1
4
+ Summary: Simple matplotlib and PGFPlots plotting with consistent, publication-ready styling
5
+ Author: hmblair
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/hmblair/hmbp
8
+ Project-URL: Repository, https://github.com/hmblair/hmbp
9
+ Keywords: plotting,matplotlib,pgfplots,latex,visualization,data-science
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Topic :: Scientific/Engineering :: Visualization
18
+ Requires-Python: >=3.10
19
+ Description-Content-Type: text/markdown
20
+ Requires-Dist: numpy
21
+ Requires-Dist: matplotlib
22
+ Provides-Extra: dev
23
+ Requires-Dist: pytest; extra == "dev"
24
+
25
+ # hmbp
26
+
27
+ A simple matplotlib wrapper with consistent, publication-ready styling.
28
+
29
+ ## Installation
30
+
31
+ ```bash
32
+ pip install hmbp
33
+ ```
34
+
35
+ ## Style
36
+
37
+ - Font: Helvetica
38
+ - Colormap: RdPu (primary), PiYG (secondary/diverging)
39
+ - 400 DPI output
40
+ - Consistent sizing: title 15pt, labels 14pt, ticks 13pt, legend 12pt
41
+
42
+ ## Usage
43
+
44
+ ```python
45
+ import hmbp
46
+
47
+ fig, ax = hmbp.new_figure()
48
+ hmbp.line_plot(y_values, x_values, label="Model A")
49
+ hmbp.set_labels("Title", "X Label", "Y Label")
50
+ hmbp.save("output.png")
51
+ ```
52
+
53
+ ## Available Functions
54
+
55
+ | Function | Description |
56
+ |----------|-------------|
57
+ | `line_plot` | Line with optional fill and smoothing |
58
+ | `multi_line_plot` | Multiple lines on same axes with smoothing |
59
+ | `scatter_plot` | Scatter with optional color mapping |
60
+ | `histogram` | Color-mapped histogram |
61
+ | `histogram_overlay` | Overlaid histograms for comparison |
62
+ | `bar_plot` | Vertical/horizontal bars |
63
+ | `box_plot` | Box plot distributions |
64
+ | `violin_plot` | Violin plot distributions |
65
+ | `heatmap` | 2D heatmap with colorbar |
66
+ | `line_plot_with_error` | Line with shaded error region |
67
+ | `confusion_matrix` | Annotated confusion matrix |
68
+ | `roc_curve` | ROC curve with AUC |
69
+ | `precision_recall_curve` | PR curve with AP |
70
+ | `residual_plot` | Regression residuals |
71
+ | `learning_curve` | Train/val learning curves |
72
+ | `metric_comparison` | Horizontal bar comparison |
73
+ | `volcano_plot` | Volcano plot for differential analysis |
74
+
75
+ ## Smoothing
76
+
77
+ Line plots support EMA smoothing for noisy data (e.g., training curves):
78
+
79
+ ```python
80
+ # smooth=0.9 means 90% weight on previous value (heavy smoothing)
81
+ hmbp.quick_line(noisy_loss, smooth=0.9, path="smoothed.png")
82
+ hmbp.quick_lines([y1, y2], labels=["A", "B"], smooth=0.8, path="comparison.png")
83
+ ```
84
+
85
+ ## Helpers
86
+
87
+ - `new_figure(figsize)` - Create figure and axes
88
+ - `set_labels(title, xlabel, ylabel)` - Apply labels
89
+ - `save(path, fig, close)` - Save with auto-legend
90
+
91
+ ## Quick API
92
+
93
+ Single-call functions that create, label, and save in one step:
94
+
95
+ ```python
96
+ import hmbp
97
+
98
+ hmbp.quick_histogram(data, title="Scores", xlabel="Value", path="hist.png")
99
+ hmbp.quick_bar(values, labels, title="Comparison", ylabel="F1", path="bars.png")
100
+ hmbp.quick_confusion_matrix(cm, class_names=["A", "B"], path="cm.png")
101
+ ```
102
+
103
+ Available: `quick_line`, `quick_lines`, `quick_scatter`, `quick_histogram`, `quick_histogram_overlay`, `quick_bar`, `quick_heatmap`, `quick_confusion_matrix`, `quick_roc`, `quick_volcano`
104
+
105
+ ## PGFPlots Output
106
+
107
+ Generate LaTeX figures using PGFPlots for direct inclusion in papers:
108
+
109
+ ```python
110
+ import hmbp.pgfplots as pgf
111
+
112
+ # Step-by-step
113
+ pgf.new_figure()
114
+ pgf.line_plot(y, x=x, label="Data", marker="*")
115
+ pgf.set_labels(title="Results", xlabel="Time", ylabel="Value")
116
+ pgf.save("figure.tex") # Creates .tex and .pdf
117
+
118
+ # Quick API
119
+ pgf.quick_bar(values, labels, title="Comparison", path="bars.tex")
120
+ pgf.quick_histogram(data, title="Distribution", path="hist.tex")
121
+ ```
122
+
123
+ Features:
124
+ - Outputs both `.tex` and compiled `.pdf` files
125
+ - Helvetica font, clean axis styling, y-major grids
126
+ - Supports `line_plot`, `multi_line_plot`, `bar_plot`, `histogram`
127
+ - Log scale via `new_figure(ymode='log')`
128
+
129
+ Requires a LaTeX distribution with `lualatex` or `pdflatex`.
hmbp-0.2.1/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # hmbp
2
+
3
+ A simple matplotlib wrapper with consistent, publication-ready styling.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pip install hmbp
9
+ ```
10
+
11
+ ## Style
12
+
13
+ - Font: Helvetica
14
+ - Colormap: RdPu (primary), PiYG (secondary/diverging)
15
+ - 400 DPI output
16
+ - Consistent sizing: title 15pt, labels 14pt, ticks 13pt, legend 12pt
17
+
18
+ ## Usage
19
+
20
+ ```python
21
+ import hmbp
22
+
23
+ fig, ax = hmbp.new_figure()
24
+ hmbp.line_plot(y_values, x_values, label="Model A")
25
+ hmbp.set_labels("Title", "X Label", "Y Label")
26
+ hmbp.save("output.png")
27
+ ```
28
+
29
+ ## Available Functions
30
+
31
+ | Function | Description |
32
+ |----------|-------------|
33
+ | `line_plot` | Line with optional fill and smoothing |
34
+ | `multi_line_plot` | Multiple lines on same axes with smoothing |
35
+ | `scatter_plot` | Scatter with optional color mapping |
36
+ | `histogram` | Color-mapped histogram |
37
+ | `histogram_overlay` | Overlaid histograms for comparison |
38
+ | `bar_plot` | Vertical/horizontal bars |
39
+ | `box_plot` | Box plot distributions |
40
+ | `violin_plot` | Violin plot distributions |
41
+ | `heatmap` | 2D heatmap with colorbar |
42
+ | `line_plot_with_error` | Line with shaded error region |
43
+ | `confusion_matrix` | Annotated confusion matrix |
44
+ | `roc_curve` | ROC curve with AUC |
45
+ | `precision_recall_curve` | PR curve with AP |
46
+ | `residual_plot` | Regression residuals |
47
+ | `learning_curve` | Train/val learning curves |
48
+ | `metric_comparison` | Horizontal bar comparison |
49
+ | `volcano_plot` | Volcano plot for differential analysis |
50
+
51
+ ## Smoothing
52
+
53
+ Line plots support EMA smoothing for noisy data (e.g., training curves):
54
+
55
+ ```python
56
+ # smooth=0.9 means 90% weight on previous value (heavy smoothing)
57
+ hmbp.quick_line(noisy_loss, smooth=0.9, path="smoothed.png")
58
+ hmbp.quick_lines([y1, y2], labels=["A", "B"], smooth=0.8, path="comparison.png")
59
+ ```
60
+
61
+ ## Helpers
62
+
63
+ - `new_figure(figsize)` - Create figure and axes
64
+ - `set_labels(title, xlabel, ylabel)` - Apply labels
65
+ - `save(path, fig, close)` - Save with auto-legend
66
+
67
+ ## Quick API
68
+
69
+ Single-call functions that create, label, and save in one step:
70
+
71
+ ```python
72
+ import hmbp
73
+
74
+ hmbp.quick_histogram(data, title="Scores", xlabel="Value", path="hist.png")
75
+ hmbp.quick_bar(values, labels, title="Comparison", ylabel="F1", path="bars.png")
76
+ hmbp.quick_confusion_matrix(cm, class_names=["A", "B"], path="cm.png")
77
+ ```
78
+
79
+ Available: `quick_line`, `quick_lines`, `quick_scatter`, `quick_histogram`, `quick_histogram_overlay`, `quick_bar`, `quick_heatmap`, `quick_confusion_matrix`, `quick_roc`, `quick_volcano`
80
+
81
+ ## PGFPlots Output
82
+
83
+ Generate LaTeX figures using PGFPlots for direct inclusion in papers:
84
+
85
+ ```python
86
+ import hmbp.pgfplots as pgf
87
+
88
+ # Step-by-step
89
+ pgf.new_figure()
90
+ pgf.line_plot(y, x=x, label="Data", marker="*")
91
+ pgf.set_labels(title="Results", xlabel="Time", ylabel="Value")
92
+ pgf.save("figure.tex") # Creates .tex and .pdf
93
+
94
+ # Quick API
95
+ pgf.quick_bar(values, labels, title="Comparison", path="bars.tex")
96
+ pgf.quick_histogram(data, title="Distribution", path="hist.tex")
97
+ ```
98
+
99
+ Features:
100
+ - Outputs both `.tex` and compiled `.pdf` files
101
+ - Helvetica font, clean axis styling, y-major grids
102
+ - Supports `line_plot`, `multi_line_plot`, `bar_plot`, `histogram`
103
+ - Log scale via `new_figure(ymode='log')`
104
+
105
+ Requires a LaTeX distribution with `lualatex` or `pdflatex`.
@@ -0,0 +1,152 @@
1
+ """
2
+ Sample PGFPlots figures demonstrating the hmbp.pgfplots module.
3
+
4
+ This script generates .tex files and compiles them to PDF.
5
+ Requires a LaTeX distribution with lualatex or pdflatex.
6
+ """
7
+
8
+ import numpy as np
9
+ from pathlib import Path
10
+
11
+ import hmbp.pgfplots as pgf
12
+
13
+ # Output directory
14
+ OUTPUT_DIR = Path(__file__).parent.parent / "figures" / "pgfplots"
15
+ OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
16
+
17
+
18
+ def line_plot_example():
19
+ """Generate a line plot with markers."""
20
+ x = np.array([0, 1, 2, 3, 4, 5])
21
+ y = np.array([1.2, 2.5, 1.8, 4.2, 3.5, 5.1])
22
+
23
+ pgf.new_figure()
24
+ pgf.line_plot(y, x=x, label="Measurements", marker="*")
25
+ pgf.set_labels(
26
+ title="Sample Line Plot",
27
+ xlabel="Time (s)",
28
+ ylabel="Value",
29
+ )
30
+ pdf = pgf.save(OUTPUT_DIR / "line_plot.tex")
31
+ print(f"Line plot: {pdf or 'tex only'}")
32
+
33
+
34
+ def multi_line_example():
35
+ """Generate a plot with multiple lines."""
36
+ x = np.linspace(0, 10, 20)
37
+ y1 = np.sin(x)
38
+ y2 = np.cos(x)
39
+ y3 = np.sin(x) * 0.5
40
+
41
+ pgf.new_figure()
42
+ pgf.multi_line_plot(
43
+ [y1, y2, y3],
44
+ x=x,
45
+ labels=["sin(x)", "cos(x)", "0.5 sin(x)"],
46
+ marker="*",
47
+ )
48
+ pgf.set_labels(
49
+ title="Trigonometric Functions",
50
+ xlabel="x",
51
+ ylabel="y",
52
+ )
53
+ pdf = pgf.save(OUTPUT_DIR / "multi_line.tex")
54
+ print(f"Multi-line plot: {pdf or 'tex only'}")
55
+
56
+
57
+ def bar_chart_example():
58
+ """Generate a bar chart."""
59
+ values = np.array([23, 45, 12, 67, 34])
60
+ labels = ["A", "B", "C", "D", "E"]
61
+
62
+ pgf.new_figure()
63
+ pgf.bar_plot(values, labels, color="purple")
64
+ pgf.set_labels(
65
+ title="Category Comparison",
66
+ xlabel="Category",
67
+ ylabel="Count",
68
+ )
69
+ pdf = pgf.save(OUTPUT_DIR / "bar_chart.tex")
70
+ print(f"Bar chart: {pdf or 'tex only'}")
71
+
72
+
73
+ def histogram_example():
74
+ """Generate a histogram."""
75
+ np.random.seed(42)
76
+ data = np.random.normal(loc=5, scale=2, size=500)
77
+
78
+ pgf.new_figure()
79
+ pgf.histogram(data, bins=15, color="purple")
80
+ pgf.set_labels(
81
+ title="Distribution",
82
+ xlabel="Value",
83
+ ylabel="Count",
84
+ )
85
+ pdf = pgf.save(OUTPUT_DIR / "histogram.tex")
86
+ print(f"Histogram: {pdf or 'tex only'}")
87
+
88
+
89
+ def log_scale_example():
90
+ """Generate a line plot with logarithmic y-axis."""
91
+ x = np.array([1, 2, 3, 4, 5, 6])
92
+ y = np.array([10, 100, 1000, 5000, 20000, 100000])
93
+
94
+ pgf.new_figure(ymode="log")
95
+ pgf.line_plot(y, x=x, label="Exponential Growth", marker="square*")
96
+ pgf.set_labels(
97
+ title="Logarithmic Scale",
98
+ xlabel="Step",
99
+ ylabel="Value",
100
+ )
101
+ pdf = pgf.save(OUTPUT_DIR / "log_scale.tex")
102
+ print(f"Log scale plot: {pdf or 'tex only'}")
103
+
104
+
105
+ def quick_api_example():
106
+ """Demonstrate quick API functions."""
107
+ # Quick line plot
108
+ y = [1, 3, 2, 5, 4, 6]
109
+ pdf = pgf.quick_line(
110
+ y,
111
+ title="Quick Line",
112
+ xlabel="X",
113
+ ylabel="Y",
114
+ path=OUTPUT_DIR / "quick_line.tex",
115
+ )
116
+ print(f"Quick line: {pdf or 'tex only'}")
117
+
118
+ # Quick bar chart
119
+ pdf = pgf.quick_bar(
120
+ [10, 25, 15, 30],
121
+ ["Q1", "Q2", "Q3", "Q4"],
122
+ title="Quarterly Results",
123
+ xlabel="Quarter",
124
+ ylabel="Revenue",
125
+ path=OUTPUT_DIR / "quick_bar.tex",
126
+ )
127
+ print(f"Quick bar: {pdf or 'tex only'}")
128
+
129
+ # Quick histogram
130
+ np.random.seed(123)
131
+ data = np.random.exponential(scale=2, size=300)
132
+ pdf = pgf.quick_histogram(
133
+ data,
134
+ bins=12,
135
+ title="Exponential Distribution",
136
+ xlabel="Value",
137
+ path=OUTPUT_DIR / "quick_histogram.tex",
138
+ )
139
+ print(f"Quick histogram: {pdf or 'tex only'}")
140
+
141
+
142
+ if __name__ == "__main__":
143
+ print("Generating PGFPlots examples...\n")
144
+
145
+ line_plot_example()
146
+ multi_line_example()
147
+ bar_chart_example()
148
+ histogram_example()
149
+ log_scale_example()
150
+ quick_api_example()
151
+
152
+ print(f"\nOutput directory: {OUTPUT_DIR}")
@@ -0,0 +1,167 @@
1
+ """Generate sample plots to demonstrate the hmbp plotting module."""
2
+
3
+ import numpy as np
4
+ import hmbp
5
+
6
+ np.random.seed(42)
7
+
8
+ # 1. Line plot
9
+ fig, ax = hmbp.new_figure()
10
+ x = np.linspace(0, 10, 100)
11
+ hmbp.line_plot(np.sin(x), x, label="Model A")
12
+ hmbp.line_plot(np.cos(x), x, label="Model B", cmap=hmbp.CMAP_ALT)
13
+ hmbp.set_labels("Training Loss Over Time", "Epoch", "Loss")
14
+ hmbp.save("figures/01_line_plot.png")
15
+
16
+ # 2. Scatter plot
17
+ fig, ax = hmbp.new_figure()
18
+ x = np.random.randn(200)
19
+ y = 0.5 * x + np.random.randn(200) * 0.3
20
+ hmbp.scatter_plot(x, y, c=y, label="Samples")
21
+ hmbp.set_labels("Feature Correlation", "Feature A", "Feature B")
22
+ hmbp.save("figures/02_scatter_plot.png")
23
+
24
+ # 3. Histogram
25
+ fig, ax = hmbp.new_figure()
26
+ data = np.concatenate([np.random.randn(500), np.random.randn(300) + 3])
27
+ hmbp.histogram(data, bins=40)
28
+ hmbp.set_labels("Score Distribution", "Score", "Count")
29
+ hmbp.save("figures/03_histogram.png")
30
+
31
+ # 4. Bar plot
32
+ fig, ax = hmbp.new_figure()
33
+ models = ["Random Forest", "XGBoost", "Neural Net", "SVM", "LogReg"]
34
+ scores = [0.92, 0.95, 0.91, 0.88, 0.85]
35
+ hmbp.bar_plot(scores, models)
36
+ hmbp.set_labels("Model Comparison", "", "F1 Score")
37
+ hmbp.save("figures/04_bar_plot.png")
38
+
39
+ # 5. Box plot
40
+ fig, ax = hmbp.new_figure()
41
+ data = [np.random.randn(100) + i * 0.5 for i in range(4)]
42
+ hmbp.box_plot(data, ["Model A", "Model B", "Model C", "Model D"])
43
+ hmbp.set_labels("Score Distribution by Model", "", "Score")
44
+ hmbp.save("figures/05_box_plot.png")
45
+
46
+ # 6. Violin plot
47
+ fig, ax = hmbp.new_figure()
48
+ data = [np.random.randn(100) * (i + 1) * 0.3 for i in range(4)]
49
+ hmbp.violin_plot(data, ["Small", "Medium", "Large", "XL"])
50
+ hmbp.set_labels("Prediction Variance by Model Size", "", "Prediction Error")
51
+ hmbp.save("figures/06_violin_plot.png")
52
+
53
+ # 7. Heatmap (correlation matrix)
54
+ fig, ax = hmbp.new_figure()
55
+ corr = np.random.randn(6, 6)
56
+ corr = (corr + corr.T) / 2
57
+ np.fill_diagonal(corr, 1)
58
+ features = ["feat_1", "feat_2", "feat_3", "feat_4", "feat_5", "feat_6"]
59
+ hmbp.heatmap(corr, xticklabels=features, yticklabels=features,
60
+ colorbar_label="Correlation", center_zero=True, annot=True)
61
+ hmbp.set_labels("Feature Correlation Matrix", "", "")
62
+ hmbp.save("figures/07_heatmap.png")
63
+
64
+ # 8. Line plot with error
65
+ fig, ax = hmbp.new_figure()
66
+ x = np.arange(10)
67
+ y = np.exp(-x * 0.3) + 0.1
68
+ yerr = 0.05 + 0.02 * np.random.randn(10)
69
+ hmbp.line_plot_with_error(y, np.abs(yerr), x, label="Mean +/- Std")
70
+ hmbp.set_labels("Convergence with Uncertainty", "Iteration", "Loss")
71
+ hmbp.save("figures/08_line_with_error.png")
72
+
73
+ # 9. Confusion matrix
74
+ fig, ax = hmbp.new_figure()
75
+ cm = np.array([[85, 10, 5], [8, 82, 10], [4, 12, 84]])
76
+ hmbp.confusion_matrix(cm, class_names=["Cat", "Dog", "Bird"], normalize=True)
77
+ hmbp.set_labels("Classification Results", "", "")
78
+ hmbp.save("figures/09_confusion_matrix.png")
79
+
80
+ # 10. ROC curve
81
+ fig, ax = hmbp.new_figure()
82
+ fpr1 = np.linspace(0, 1, 100)
83
+ tpr1 = np.sqrt(fpr1) # Good model
84
+ tpr2 = fpr1 ** 2 + fpr1 * 0.5 # Mediocre model
85
+ tpr2 = np.clip(tpr2, 0, 1)
86
+ hmbp.roc_curve(fpr1, tpr1, auc=0.92, label="XGBoost")
87
+ hmbp.roc_curve(fpr1, tpr2, auc=0.71, label="Baseline", cmap=hmbp.CMAP_ALT)
88
+ hmbp.set_labels("ROC Comparison", "", "")
89
+ hmbp.save("figures/10_roc_curve.png")
90
+
91
+ # 11. Precision-Recall curve
92
+ fig, ax = hmbp.new_figure()
93
+ recall = np.linspace(0, 1, 100)
94
+ precision1 = 1 - 0.3 * recall ** 2
95
+ precision2 = 1 - 0.6 * recall
96
+ hmbp.precision_recall_curve(precision1, recall, ap=0.89, label="Model A")
97
+ hmbp.precision_recall_curve(precision2, recall, ap=0.72, label="Model B", cmap=hmbp.CMAP_ALT)
98
+ hmbp.set_labels("Precision-Recall Comparison", "", "")
99
+ hmbp.save("figures/11_pr_curve.png")
100
+
101
+ # 12. Residual plot
102
+ fig, ax = hmbp.new_figure()
103
+ y_pred = np.linspace(0, 10, 100)
104
+ y_true = y_pred + np.random.randn(100) * 0.5
105
+ hmbp.residual_plot(y_true, y_pred)
106
+ hmbp.set_labels("Residual Analysis", "", "")
107
+ hmbp.save("figures/12_residual_plot.png")
108
+
109
+ # 13. Learning curve
110
+ fig, ax = hmbp.new_figure()
111
+ sizes = np.array([100, 200, 500, 1000, 2000, 5000])
112
+ train_scores = np.column_stack([
113
+ 0.99 - 0.1 * np.exp(-sizes / 500) + np.random.randn(6) * 0.01
114
+ for _ in range(5)
115
+ ])
116
+ val_scores = np.column_stack([
117
+ 0.85 + 0.1 * (1 - np.exp(-sizes / 1000)) + np.random.randn(6) * 0.02
118
+ for _ in range(5)
119
+ ])
120
+ hmbp.learning_curve(train_scores, val_scores, sizes, metric_name="Accuracy")
121
+ hmbp.set_labels("Learning Curve", "", "")
122
+ hmbp.save("figures/13_learning_curve.png")
123
+
124
+ # 14. Metric comparison
125
+ fig, ax = hmbp.new_figure()
126
+ metrics = {
127
+ "Accuracy": 0.94,
128
+ "Precision": 0.91,
129
+ "Recall": 0.88,
130
+ "F1": 0.89,
131
+ "AUC": 0.96
132
+ }
133
+ hmbp.metric_comparison(metrics)
134
+ hmbp.set_labels("Model Metrics", "", "")
135
+ hmbp.save("figures/14_metric_comparison.png")
136
+
137
+ # 15. Histogram overlay
138
+ fig, ax = hmbp.new_figure()
139
+ data1 = np.random.randn(500) * 0.8
140
+ data2 = np.random.randn(500) * 1.2 + 1.5
141
+ data3 = np.random.randn(500) * 0.6 + 3
142
+ hmbp.histogram_overlay([data1, data2, data3], labels=["MLP", "Attention", "Ground Truth"], bins=30)
143
+ hmbp.set_labels("Score Distributions by Model", "Score", "Count")
144
+ hmbp.save("figures/15_histogram_overlay.png")
145
+
146
+ # 16. Multi-line plot with noisy data and smoothing
147
+ fig, ax = hmbp.new_figure()
148
+ x = np.arange(100)
149
+ y1 = np.exp(-x * 0.03) + np.random.randn(100) * 0.08
150
+ y2 = np.exp(-x * 0.025) * 0.9 + np.random.randn(100) * 0.08
151
+ y3 = np.exp(-x * 0.035) * 1.1 + np.random.randn(100) * 0.08
152
+ hmbp.multi_line_plot([y1, y2, y3], x, labels=["Adam", "SGD", "AdamW"], smooth=0.9)
153
+ hmbp.set_labels("Training Loss Comparison (Smoothed)", "Epoch", "Loss")
154
+ hmbp.save("figures/16_multi_line.png")
155
+
156
+ # 17. Raw vs smoothed comparison
157
+ import matplotlib.pyplot as plt
158
+ fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
159
+ x = np.arange(100)
160
+ y = np.exp(-x * 0.03) + np.random.randn(100) * 0.15
161
+ hmbp.line_plot(y, x, label="Raw", ax=ax1, fill=False)
162
+ hmbp.set_labels("Raw Training Curve", "Epoch", "Loss", ax=ax1)
163
+ hmbp.line_plot(y, x, label="Smoothed (0.9)", ax=ax2, fill=False, smooth=0.9)
164
+ hmbp.set_labels("EMA Smoothed (weight=0.9)", "Epoch", "Loss", ax=ax2)
165
+ hmbp.save("figures/17_smoothing_comparison.png")
166
+
167
+ print("Generated 17 sample plots in figures/")