plotcli-py 0.1.0__py3-none-any.whl
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.
- CLAUDE.md +51 -0
- LICENSE +21 -0
- PKG-INFO +358 -0
- README.md +340 -0
- main.py +6 -0
- plotcli-original/.Rbuildignore +18 -0
- plotcli-original/.github/workflows/deploy_docs.yml +43 -0
- plotcli-original/.gitignore +46 -0
- plotcli-original/DESCRIPTION +25 -0
- plotcli-original/NAMESPACE +60 -0
- plotcli-original/NEWS.md +112 -0
- plotcli-original/R/ascii_escape.r +13 -0
- plotcli-original/R/canvas.r +586 -0
- plotcli-original/R/class_functions.r +114 -0
- plotcli-original/R/geom_registry.r +1376 -0
- plotcli-original/R/ggplotcli.r +234 -0
- plotcli-original/R/ggplotcli_helpers.r +1099 -0
- plotcli-original/R/helper_functions.r +351 -0
- plotcli-original/R/plotcli.r +963 -0
- plotcli-original/R/plotcli_grid.r +1 -0
- plotcli-original/R/plotcli_wrappers.r +416 -0
- plotcli-original/R/zzz.r +15 -0
- plotcli-original/README.md +192 -0
- plotcli-original/docs/ascii.png +0 -0
- plotcli-original/docs/bar.png +0 -0
- plotcli-original/docs/block.png +0 -0
- plotcli-original/docs/boxplot.png +0 -0
- plotcli-original/docs/density.png +0 -0
- plotcli-original/docs/facet.png +0 -0
- plotcli-original/docs/facet_grid.png +0 -0
- plotcli-original/docs/generate_png.sh +137 -0
- plotcli-original/docs/heatmap.png +0 -0
- plotcli-original/docs/histogram.png +0 -0
- plotcli-original/docs/line.png +0 -0
- plotcli-original/docs/noborder.png +0 -0
- plotcli-original/docs/scatter.png +0 -0
- plotcli-original/docs/showcase.R +182 -0
- plotcli-original/inst/doc/ggplotcli.R +231 -0
- plotcli-original/inst/doc/ggplotcli.Rmd +329 -0
- plotcli-original/inst/doc/ggplotcli.html +1078 -0
- plotcli-original/inst/doc/plotcli_class.R +98 -0
- plotcli-original/inst/doc/plotcli_class.Rmd +121 -0
- plotcli-original/inst/doc/plotcli_class.html +564 -0
- plotcli-original/inst/doc/plotcli_wrappers.R +35 -0
- plotcli-original/inst/doc/plotcli_wrappers.Rmd +62 -0
- plotcli-original/inst/doc/plotcli_wrappers.html +546 -0
- plotcli-original/man/AsciiCanvas.Rd +116 -0
- plotcli-original/man/BlockCanvas.Rd +132 -0
- plotcli-original/man/BrailleCanvas.Rd +146 -0
- plotcli-original/man/Canvas.Rd +492 -0
- plotcli-original/man/GeomRegistry.Rd +9 -0
- plotcli-original/man/add_legend_to_output.Rd +12 -0
- plotcli-original/man/braille_dot_bit.Rd +29 -0
- plotcli-original/man/braille_set_dot.Rd +21 -0
- plotcli-original/man/bresenham.Rd +27 -0
- plotcli-original/man/build_plot_output.Rd +28 -0
- plotcli-original/man/build_plot_output_v2.Rd +41 -0
- plotcli-original/man/cat_plot_matrix.Rd +17 -0
- plotcli-original/man/cbind.plotcli.Rd +19 -0
- plotcli-original/man/cbind_plots.Rd +17 -0
- plotcli-original/man/color_to_term.Rd +18 -0
- plotcli-original/man/create_canvas.Rd +21 -0
- plotcli-original/man/create_panel_scales.Rd +29 -0
- plotcli-original/man/create_scales.Rd +27 -0
- plotcli-original/man/dot-geom_registry.Rd +16 -0
- plotcli-original/man/draw_border.Rd +12 -0
- plotcli-original/man/draw_grid.Rd +12 -0
- plotcli-original/man/extract_legend_info.Rd +12 -0
- plotcli-original/man/extract_plot_labels.Rd +12 -0
- plotcli-original/man/extract_plot_style.Rd +12 -0
- plotcli-original/man/format_axis_label.Rd +18 -0
- plotcli-original/man/format_four_chars.Rd +21 -0
- plotcli-original/man/geom_area_handler.Rd +12 -0
- plotcli-original/man/geom_bar_handler.Rd +12 -0
- plotcli-original/man/geom_boxplot_handler.Rd +13 -0
- plotcli-original/man/geom_density_handler.Rd +12 -0
- plotcli-original/man/geom_histogram_handler.Rd +12 -0
- plotcli-original/man/geom_hline_handler.Rd +12 -0
- plotcli-original/man/geom_line_handler.Rd +12 -0
- plotcli-original/man/geom_path_handler.Rd +12 -0
- plotcli-original/man/geom_point_handler.Rd +12 -0
- plotcli-original/man/geom_rect_handler.Rd +12 -0
- plotcli-original/man/geom_segment_handler.Rd +12 -0
- plotcli-original/man/geom_smooth_handler.Rd +12 -0
- plotcli-original/man/geom_text_handler.Rd +12 -0
- plotcli-original/man/geom_vline_handler.Rd +12 -0
- plotcli-original/man/get_color_hue.Rd +18 -0
- plotcli-original/man/get_data_subset.Rd +23 -0
- plotcli-original/man/get_facet_info.Rd +18 -0
- plotcli-original/man/get_geom_handler.Rd +17 -0
- plotcli-original/man/get_term_colors.Rd +21 -0
- plotcli-original/man/ggplotcli.Rd +83 -0
- plotcli-original/man/init_color_mapping.Rd +15 -0
- plotcli-original/man/is_braille.Rd +20 -0
- plotcli-original/man/is_geom_registered.Rd +17 -0
- plotcli-original/man/list_registered_geoms.Rd +14 -0
- plotcli-original/man/make_colored.Rd +23 -0
- plotcli-original/man/make_unique_names.Rd +20 -0
- plotcli-original/man/normalize_data.Rd +27 -0
- plotcli-original/man/pclib.Rd +48 -0
- plotcli-original/man/pclibx.Rd +46 -0
- plotcli-original/man/pclid.Rd +44 -0
- plotcli-original/man/pclih.Rd +50 -0
- plotcli-original/man/pclil.Rd +48 -0
- plotcli-original/man/pclis.Rd +48 -0
- plotcli-original/man/pixel_to_braille.Rd +23 -0
- plotcli-original/man/plotcli.Rd +598 -0
- plotcli-original/man/plotcli_bar.Rd +48 -0
- plotcli-original/man/plotcli_box.Rd +46 -0
- plotcli-original/man/plotcli_density.Rd +44 -0
- plotcli-original/man/plotcli_histogram.Rd +50 -0
- plotcli-original/man/plotcli_line.Rd +48 -0
- plotcli-original/man/plotcli_options.Rd +18 -0
- plotcli-original/man/plotcli_scatter.Rd +48 -0
- plotcli-original/man/plus-.plotcli.Rd +19 -0
- plotcli-original/man/rbind.plotcli.Rd +19 -0
- plotcli-original/man/rbind_plots.Rd +17 -0
- plotcli-original/man/register_geom.Rd +21 -0
- plotcli-original/man/remove_color_codes.Rd +21 -0
- plotcli-original/man/render_faceted_plot.Rd +25 -0
- plotcli-original/man/render_single_panel.Rd +12 -0
- plotcli-original/man/safe_aes_name.Rd +18 -0
- plotcli-original/tests/testthat/test-new-geoms.R +136 -0
- plotcli-original/tests/testthat/test-plotcli.R +69 -0
- plotcli-original/tests/testthat.R +4 -0
- plotcli-original/vignettes/ggplotcli.Rmd +329 -0
- plotcli-original/vignettes/plotcli_class.R +98 -0
- plotcli-original/vignettes/plotcli_class.Rmd +121 -0
- plotcli-original/vignettes/plotcli_wrappers.R +35 -0
- plotcli-original/vignettes/plotcli_wrappers.Rmd +62 -0
- plotcli.egg-info/PKG-INFO +11 -0
- plotcli.egg-info/SOURCES.txt +7 -0
- plotcli.egg-info/dependency_links.txt +1 -0
- plotcli.egg-info/entry_points.txt +3 -0
- plotcli.egg-info/top_level.txt +1 -0
- plotcli.py +978 -0
- plotcli_py-0.1.0.dist-info/METADATA +358 -0
- plotcli_py-0.1.0.dist-info/RECORD +143 -0
- plotcli_py-0.1.0.dist-info/WHEEL +4 -0
- plotcli_py-0.1.0.dist-info/entry_points.txt +2 -0
- plotcli_py-0.1.0.dist-info/licenses/LICENSE +21 -0
- pyproject.toml +31 -0
- uv.lock +8 -0
README.md
ADDED
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
# plotcli
|
|
2
|
+
|
|
3
|
+
Terminal plotting in Python using Unicode Braille characters, block elements, or ASCII. Zero dependencies. Designed for CLI workflows and AI coding assistants like Claude Code.
|
|
4
|
+
|
|
5
|
+
Inspired by the R [plotcli](https://github.com/cheuerde/plotcli) package and Julia's [UnicodePlots.jl](https://github.com/JuliaPlots/UnicodePlots.jl).
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# With uv (recommended)
|
|
11
|
+
uv tool install plotcli
|
|
12
|
+
|
|
13
|
+
# With pip
|
|
14
|
+
pip install plotcli
|
|
15
|
+
|
|
16
|
+
# Or run directly without installing
|
|
17
|
+
uvx plotcli fn "sin(x)" 0 6.28
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Quick Start
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
# Pipe data
|
|
24
|
+
echo "1 4 9 16 25 36 49 64 81 100" | plotcli line
|
|
25
|
+
|
|
26
|
+
# Plot a math function
|
|
27
|
+
plotcli fn "sin(x)" 0 6.28
|
|
28
|
+
|
|
29
|
+
# From a Python expression
|
|
30
|
+
plotcli scatter -e "[(x, x**2) for x in range(50)]"
|
|
31
|
+
|
|
32
|
+
# From a CSV file
|
|
33
|
+
plotcli line -f data.csv -x time -y value
|
|
34
|
+
|
|
35
|
+
# Pipe from other commands
|
|
36
|
+
seq 100 | awk '{print sin($1/10)}' | plotcli line
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Examples
|
|
40
|
+
|
|
41
|
+
### Line Plot
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
echo "1 4 9 16 25 36 49 64 81 100" | plotcli line --title "Squares"
|
|
45
|
+
```
|
|
46
|
+
```
|
|
47
|
+
Squares
|
|
48
|
+
┌───────────────────────────────────────────────────────┐
|
|
49
|
+
100 ┤ ⢀⠤⠊│
|
|
50
|
+
│ ⡠⠒⠁ │
|
|
51
|
+
80.2 ┤ ⡠⠔⠉ │
|
|
52
|
+
│ ⡠⠔⠉ │
|
|
53
|
+
60.4 ┤ ⢀⡠⠔⠉ │
|
|
54
|
+
│ ⣀⠤⠒⠁ │
|
|
55
|
+
y │ ⢀⡠⠔⠊ │
|
|
56
|
+
40.6 ┤ ⣀⠤⠔⠊⠁ │
|
|
57
|
+
│ ⣀⠤⠒⠉ │
|
|
58
|
+
20.8 ┤ ⣀⡠⠤⠒⠊⠉ │
|
|
59
|
+
│ ⢀⣀⡠⠤⠔⠒⠊⠉ │
|
|
60
|
+
1 ┤⣀⣀⣀⡠⠤⠤⠤⠔⠒⠊⠉⠁ │
|
|
61
|
+
└───────────────────────────────────────────────────────┘
|
|
62
|
+
0 2.25 4.5 6.75 9
|
|
63
|
+
x
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Math Functions
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
plotcli fn "sin(x)" 0 6.28 --title "Sine Wave"
|
|
70
|
+
```
|
|
71
|
+
```
|
|
72
|
+
Sine Wave
|
|
73
|
+
┌───────────────────────────────────────────────────────┐
|
|
74
|
+
1 ┤ ⣀⠴⠒⠋⠉⠉⠙⠒⠤⣀ │
|
|
75
|
+
│ ⢀⡴⠋⠁ ⠈⠳⢄ │
|
|
76
|
+
0.6 ┤ ⢀⡤⠋ ⠑⣄ │
|
|
77
|
+
│ ⢠⠊ ⠈⠱⡄ │
|
|
78
|
+
f 0.2 ┤ ⢀⠜⠁ ⠘⢆ │
|
|
79
|
+
( │⢠⠊ ⠱⡄ │
|
|
80
|
+
x │⠁ ⠘⢆ ⣠⠋│
|
|
81
|
+
) -0.2 ┤ ⠱⡄ ⡔⠁ │
|
|
82
|
+
│ ⠈⢆⡀ ⡠⠋ │
|
|
83
|
+
-0.6 ┤ ⠙⢄ ⣠⠚⠁ │
|
|
84
|
+
│ ⠑⢦⡀ ⢀⣠⠞⠁ │
|
|
85
|
+
-1 ┤ ⠉⠒⠤⣄⣀⣀⣠⠤⠖⠋ │
|
|
86
|
+
└───────────────────────────────────────────────────────┘
|
|
87
|
+
0 1.57 3.14 4.71 6.28
|
|
88
|
+
x
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Built-in math: `sin`, `cos`, `tan`, `sqrt`, `log`, `exp`, `pi`, `e`, and Python's `math` module.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
plotcli fn "exp(-x/5) * cos(x*2)" 0 15 --title "Damped Oscillation"
|
|
95
|
+
plotcli fn "x**3 - 3*x" -3 3 --title "Cubic"
|
|
96
|
+
plotcli fn "log(x)" 0.1 10 --title "Logarithm"
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Histogram
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
plotcli hist -e "[random.gauss(0,1) for _ in range(500)]" --title "Normal Distribution"
|
|
103
|
+
```
|
|
104
|
+
```
|
|
105
|
+
Normal Distribution
|
|
106
|
+
┌───────────────────────────────────────────────────────┐
|
|
107
|
+
62 ┤ ⣿⡇ │
|
|
108
|
+
│ ⣿⡇⢸⣿ │
|
|
109
|
+
49.6 ┤ ⢰⣶ ⣿⡇⢸⣿ ⣿⡇⢰⣶ │
|
|
110
|
+
│ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ │
|
|
111
|
+
c 37.2 ┤ ⢸⣿ ⢰⣶ ⣿⡇⢸⣿ ⣿⡇⢸⣿ │
|
|
112
|
+
o │ ⣀⡀⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ │
|
|
113
|
+
u │ ⢰⣶ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ │
|
|
114
|
+
n 24.8 ┤ ⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣀⡀ ⣤⡄ │
|
|
115
|
+
t │ ⣶⡆⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇ │
|
|
116
|
+
12.4 ┤ ⢰⣶ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇⢠⣤ ⣶⡆ │
|
|
117
|
+
│ ⣀⡀⢸⣿ ⢠⣤ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇⢸⣿ ⣿⡇⢠⣤ ⣤⡄ │
|
|
118
|
+
0 ┤⣶ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣀⡀⢀⣀ ⣶│
|
|
119
|
+
└───────────────────────────────────────────────────────┘
|
|
120
|
+
-2.48 -1.06 0.36 1.78 3.2
|
|
121
|
+
x
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Density Plot
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
plotcli density -e "[random.gauss(0,1) for _ in range(1000)]" --title "Kernel Density"
|
|
128
|
+
```
|
|
129
|
+
```
|
|
130
|
+
Kernel Density
|
|
131
|
+
┌───────────────────────────────────────────────────────┐
|
|
132
|
+
0.38 ┤ ⢀⠤⠒⠊⠉⠉⠢⢄ │
|
|
133
|
+
│ ⢰⠁ ⢣ │
|
|
134
|
+
0.3 ┤ ⢠⠃ ⢣ │
|
|
135
|
+
d │ ⡎ ⢣ │
|
|
136
|
+
e 0.23 ┤ ⡜ ⢣ │
|
|
137
|
+
n │ ⡰⠁ ⠑⡄ │
|
|
138
|
+
s │ ⢀⠎ ⠘⡄ │
|
|
139
|
+
i 0.15 ┤ ⢀⠎ ⠱⡀ │
|
|
140
|
+
t │ ⢀⠎ ⢣ │
|
|
141
|
+
y 0.08 ┤ ⢠⠊ ⠱⡀ │
|
|
142
|
+
│ ⢀⠤⠒⠁ ⠈⠑⠤⡀ │
|
|
143
|
+
1.7e-05 ┤⣀⣀⣀⣀⣀⣀⣀⡠⠤⠔⠊⠁ ⠈⠑⠢⠤⠤⢄⣀⣀⣀⣀⣀⣀│
|
|
144
|
+
└───────────────────────────────────────────────────────┘
|
|
145
|
+
-4.01 -2.01 -0.02 1.97 3.96
|
|
146
|
+
x
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Boxplot
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
plotcli boxplot \
|
|
153
|
+
-e "[[random.gauss(m, 1+i*0.3) for _ in range(100)] for i, m in enumerate([0, 3, 7])]" \
|
|
154
|
+
--title "Boxplots"
|
|
155
|
+
```
|
|
156
|
+
```
|
|
157
|
+
Boxplots
|
|
158
|
+
┌───────────────────────────────────────────────────────┐
|
|
159
|
+
10.45 ┤ ⠈⠉⢹⠉⠉ │
|
|
160
|
+
│ ⢸ │
|
|
161
|
+
7.83 ┤ ⡖⠒⠒⠒⠚⠒⠒⠒⠒⡆ │
|
|
162
|
+
│ ⢀ ⡏⠉⠉⠉⠉⠉⠉⠉⠉⡇ │
|
|
163
|
+
v 5.22 ┤ ⠐⠒⢲⠒⠒ ⠉⠉⠉⠉⢹⠉⠉⠉⠉⠁ │
|
|
164
|
+
a │ ⢸ ⢸ │
|
|
165
|
+
l │ ⣖⣒⣒⣒⣚⣒⣒⣒⣒⡆ ⢀⣀⣸⣀⣀ │
|
|
166
|
+
u 2.6 ┤ ⠒⠒⡖⠒⠂ ⠧⠤⠤⠤⢤⠤⠤⠤⠤⠇ ⠐ │
|
|
167
|
+
e │ ⢀⣀⣀⣀⣀⣇⣀⣀⣀⣀ ⢸ │
|
|
168
|
+
-0.02 ┤ ⢸⣒⣒⣒⣒⣒⣒⣒⣒⣺ ⠐⠒⠚⠒⠒ │
|
|
169
|
+
│ ⡇ │
|
|
170
|
+
-2.63 ┤ ⠉⠉⡉⠉⠁ │
|
|
171
|
+
└───────────────────────────────────────────────────────┘
|
|
172
|
+
box_1 box_2 box_3
|
|
173
|
+
x
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Scatter Plot
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
plotcli scatter \
|
|
180
|
+
-e "[(x, x**1.5 + random.gauss(0,5)) for x in range(40)]" \
|
|
181
|
+
--title "Noisy Power Law"
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Heatmap
|
|
185
|
+
|
|
186
|
+
```bash
|
|
187
|
+
plotcli heatmap \
|
|
188
|
+
-e "[[math.sin(r/3+c/3) for c in range(20)] for r in range(10)]" \
|
|
189
|
+
--title "Heatmap"
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
## Canvas Types
|
|
193
|
+
|
|
194
|
+
Three rendering backends with different resolution/compatibility tradeoffs:
|
|
195
|
+
|
|
196
|
+
### Braille (default) -- highest resolution
|
|
197
|
+
```bash
|
|
198
|
+
plotcli fn "sin(x)" 0 6.28 --canvas braille
|
|
199
|
+
```
|
|
200
|
+
Uses Unicode Braille patterns (U+2800-U+28FF). Each character cell contains a 2x4 dot grid, giving **8x** the effective resolution of ASCII.
|
|
201
|
+
|
|
202
|
+
### Block -- medium resolution
|
|
203
|
+
```bash
|
|
204
|
+
plotcli fn "sin(x)" 0 6.28 --canvas block
|
|
205
|
+
```
|
|
206
|
+
```
|
|
207
|
+
Block Canvas
|
|
208
|
+
┌───────────────────────────────────────────────────────┐
|
|
209
|
+
1 ┤ ▄▄█▀▀▀▀█▄▄ │
|
|
210
|
+
│ ▄█▀ ▀▀▄ │
|
|
211
|
+
0.6 ┤ ▄▀▀ █▄ │
|
|
212
|
+
│ ▄█▀ █▄ │
|
|
213
|
+
f 0.2 ┤ █▀ ▀█▄ │
|
|
214
|
+
( │▄█ █▄ │
|
|
215
|
+
x │▀ ▀█ █▀│
|
|
216
|
+
) -0.2 ┤ █▄ ▄█ │
|
|
217
|
+
│ ▀█ ▄█▀ │
|
|
218
|
+
-0.6 ┤ ▀█ ▄▄▀ │
|
|
219
|
+
│ ▀█▄ ▄█▀ │
|
|
220
|
+
-1 ┤ ▀▀█▄▄▄▄█▀▀ │
|
|
221
|
+
└───────────────────────────────────────────────────────┘
|
|
222
|
+
```
|
|
223
|
+
Uses half-block characters (▀ ▄ █) for 2x vertical resolution.
|
|
224
|
+
|
|
225
|
+
### ASCII -- maximum compatibility
|
|
226
|
+
```bash
|
|
227
|
+
plotcli fn "sin(x)" 0 6.28 --canvas ascii
|
|
228
|
+
```
|
|
229
|
+
```
|
|
230
|
+
ASCII Canvas
|
|
231
|
+
┌───────────────────────────────────────────────────────┐
|
|
232
|
+
1 ┤ ******** │
|
|
233
|
+
│ **** **** │
|
|
234
|
+
0.6 ┤ *** *** │
|
|
235
|
+
│ *** *** │
|
|
236
|
+
f 0.2 ┤ ** ** │
|
|
237
|
+
( │** ** │
|
|
238
|
+
x │* ** **│
|
|
239
|
+
) -0.2 ┤ ** ** │
|
|
240
|
+
│ *** *** │
|
|
241
|
+
-0.6 ┤ *** *** │
|
|
242
|
+
│ **** **** │
|
|
243
|
+
-1 ┤ ******** │
|
|
244
|
+
└───────────────────────────────────────────────────────┘
|
|
245
|
+
```
|
|
246
|
+
Works in any terminal. Uses `*` for data points.
|
|
247
|
+
|
|
248
|
+
## Data Input
|
|
249
|
+
|
|
250
|
+
| Method | Example |
|
|
251
|
+
|--------|---------|
|
|
252
|
+
| **Pipe values** | `echo "1 4 9 16" \| plotcli line` |
|
|
253
|
+
| **Pipe lines** | `seq 50 \| plotcli line` |
|
|
254
|
+
| **x,y pairs** | `echo -e "1,2\n3,4\n5,6" \| plotcli scatter -d ","` |
|
|
255
|
+
| **Expression** | `plotcli line -e "[x**2 for x in range(20)]"` |
|
|
256
|
+
| **Tuple list** | `plotcli scatter -e "[(x, sin(x)) for x in range(50)]"` |
|
|
257
|
+
| **CSV file** | `plotcli line -f data.csv -x time -y price` |
|
|
258
|
+
| **JSON** | `echo '[1,4,9,16]' \| plotcli line -j` |
|
|
259
|
+
| **Math function** | `plotcli fn "sin(x)*exp(-x/5)" 0 20` |
|
|
260
|
+
| **Shell pipeline** | `curl -s api \| jq '.[].value' \| plotcli line` |
|
|
261
|
+
|
|
262
|
+
## Options
|
|
263
|
+
|
|
264
|
+
```
|
|
265
|
+
-W, --width Canvas width in characters (auto-detected)
|
|
266
|
+
-H, --height Canvas height in characters (auto-detected)
|
|
267
|
+
-t, --title Plot title
|
|
268
|
+
--x-label X-axis label
|
|
269
|
+
--y-label Y-axis label
|
|
270
|
+
-c, --color Series color (red, green, blue, yellow, magenta, cyan, ...)
|
|
271
|
+
--canvas braille (default), block, or ascii
|
|
272
|
+
--xlim MIN MAX X-axis limits
|
|
273
|
+
--ylim MIN MAX Y-axis limits
|
|
274
|
+
--bins N Number of histogram bins
|
|
275
|
+
--no-legend Hide legend
|
|
276
|
+
-d, --delimiter Input delimiter
|
|
277
|
+
-j, --json Parse stdin as JSON
|
|
278
|
+
-e, --eval Python expression for data
|
|
279
|
+
-f, --file CSV/TSV file path
|
|
280
|
+
-x, --x-col X column name or index
|
|
281
|
+
-y, --y-col Y column name or index
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
## Use with Claude Code
|
|
285
|
+
|
|
286
|
+
plotcli is designed for AI-assisted CLI workflows. Claude Code can generate and display plots inline:
|
|
287
|
+
|
|
288
|
+
```
|
|
289
|
+
> Plot a sine wave
|
|
290
|
+
|
|
291
|
+
$ plotcli fn "sin(x)" 0 6.28 --title "Sine Wave"
|
|
292
|
+
|
|
293
|
+
> Show me the distribution of file sizes in this directory
|
|
294
|
+
|
|
295
|
+
$ find . -type f -exec stat -f%z {} \; | plotcli hist --title "File Sizes" --bins 20
|
|
296
|
+
|
|
297
|
+
> Visualize the CSV data
|
|
298
|
+
|
|
299
|
+
$ plotcli scatter -f measurements.csv -x temperature -y pressure --title "T vs P"
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
To make `plotcli` available globally for Claude Code:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
uv tool install plotcli # install globally via uv
|
|
306
|
+
# or
|
|
307
|
+
pip install plotcli # install globally via pip
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Python API
|
|
311
|
+
|
|
312
|
+
```python
|
|
313
|
+
import plotcli
|
|
314
|
+
|
|
315
|
+
# Quick one-liners
|
|
316
|
+
plotcli.line(range(10), [x**2 for x in range(10)], title="Squares").show()
|
|
317
|
+
plotcli.scatter(xs, ys, title="My Data", canvas_type="braille").show()
|
|
318
|
+
plotcli.histogram(data, bins=20, title="Distribution").show()
|
|
319
|
+
plotcli.density(data, title="KDE").show()
|
|
320
|
+
plotcli.boxplot([group_a, group_b], names=["A", "B"]).show()
|
|
321
|
+
plotcli.function_plot("sin(x)*x", 0, 10).show()
|
|
322
|
+
|
|
323
|
+
# Multi-series
|
|
324
|
+
from plotcli import Plot
|
|
325
|
+
p = Plot(title="Comparison", width=60, height=15)
|
|
326
|
+
p.add(x1, y1, "line", color="blue", name="model")
|
|
327
|
+
p.add(x2, y2, "scatter", color="red", name="data")
|
|
328
|
+
p.show()
|
|
329
|
+
|
|
330
|
+
# Get string output (no print)
|
|
331
|
+
output = p.render()
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## License
|
|
335
|
+
|
|
336
|
+
LGPL-3.0 (same as the original R plotcli)
|
|
337
|
+
|
|
338
|
+
## Credits
|
|
339
|
+
|
|
340
|
+
Python port inspired by [plotcli](https://github.com/cheuerde/plotcli) by Claas Heuer, which was in turn inspired by [UnicodePlots.jl](https://github.com/JuliaPlots/UnicodePlots.jl).
|
main.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
^\.github$
|
|
2
|
+
^\.gitignore$
|
|
3
|
+
^docs$
|
|
4
|
+
^\.lib$
|
|
5
|
+
^\.DS_Store$
|
|
6
|
+
^tools$
|
|
7
|
+
^plotcli\.Rcheck$
|
|
8
|
+
^plotcli_.*\.tar\.gz$
|
|
9
|
+
^LICENSE$
|
|
10
|
+
^demo_show\.R$
|
|
11
|
+
^mega_show\.R$
|
|
12
|
+
^ultimate_show\.R$
|
|
13
|
+
^ultra_demo\.R$
|
|
14
|
+
^reproduce_.*$
|
|
15
|
+
^vignettes_test\.R$
|
|
16
|
+
^visual_verification\..*$
|
|
17
|
+
^plotcli_docs\.Rmd$
|
|
18
|
+
^\.claude$
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Deploy Documentation
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- main
|
|
7
|
+
|
|
8
|
+
jobs:
|
|
9
|
+
build:
|
|
10
|
+
runs-on: ubuntu-latest
|
|
11
|
+
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout repository
|
|
14
|
+
uses: actions/checkout@v2
|
|
15
|
+
|
|
16
|
+
- name: Setup R
|
|
17
|
+
uses: r-lib/actions/setup-r@v2
|
|
18
|
+
|
|
19
|
+
- name: Install rmarkdown
|
|
20
|
+
run: Rscript -e 'install.packages("rmarkdown")'
|
|
21
|
+
|
|
22
|
+
- name: Install remotes
|
|
23
|
+
run: Rscript -e 'if (!requireNamespace("remotes", quietly = TRUE)) install.packages("remotes")'
|
|
24
|
+
|
|
25
|
+
- name: Install plotcli
|
|
26
|
+
env:
|
|
27
|
+
GITHUB_PAT: ${{ secrets.GH_PAGES_PAT }}
|
|
28
|
+
run: Rscript -e 'Sys.setenv(GITHUB_PAT = Sys.getenv("GITHUB_PAT")); remotes::install_github("cheuerde/plotcli", upgrade = "never")'
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
- name: Install pandoc
|
|
33
|
+
run: sudo apt update && sudo apt install -y pandoc
|
|
34
|
+
|
|
35
|
+
- name: Render RMarkdown to HTML
|
|
36
|
+
run: Rscript -e 'rmarkdown::render("plotcli_docs.Rmd", output_file = "index.html")'
|
|
37
|
+
|
|
38
|
+
- name: Deploy to GitHub Pages
|
|
39
|
+
uses: peaceiris/actions-gh-pages@v3
|
|
40
|
+
with:
|
|
41
|
+
github_token: ${{ secrets.GH_PAGES_PAT }}
|
|
42
|
+
publish_dir: ./
|
|
43
|
+
publish_branch: gh-pages
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# History files
|
|
2
|
+
.Rhistory
|
|
3
|
+
.Rapp.history
|
|
4
|
+
|
|
5
|
+
# Session Data files
|
|
6
|
+
.RData
|
|
7
|
+
.RDataTmp
|
|
8
|
+
|
|
9
|
+
# User-specific files
|
|
10
|
+
.Ruserdata
|
|
11
|
+
|
|
12
|
+
# Example code in package build process
|
|
13
|
+
*-Ex.R
|
|
14
|
+
|
|
15
|
+
# Output files from R CMD build
|
|
16
|
+
/*.tar.gz
|
|
17
|
+
|
|
18
|
+
# Output files from R CMD check
|
|
19
|
+
/*.Rcheck/
|
|
20
|
+
|
|
21
|
+
# RStudio files
|
|
22
|
+
.Rproj.user/
|
|
23
|
+
|
|
24
|
+
# produced vignettes
|
|
25
|
+
vignettes/*.html
|
|
26
|
+
vignettes/*.pdf
|
|
27
|
+
|
|
28
|
+
# OAuth2 token, see https://github.com/hadley/httr/releases/tag/v0.3
|
|
29
|
+
.httr-oauth
|
|
30
|
+
|
|
31
|
+
# knitr and R markdown default cache directories
|
|
32
|
+
*_cache/
|
|
33
|
+
/cache/
|
|
34
|
+
|
|
35
|
+
# Temporary files created by R markdown
|
|
36
|
+
*.utf8.md
|
|
37
|
+
*.knit.md
|
|
38
|
+
|
|
39
|
+
# R Environment Variables
|
|
40
|
+
.Renviron
|
|
41
|
+
|
|
42
|
+
# translation temp files
|
|
43
|
+
po/*~
|
|
44
|
+
|
|
45
|
+
# RStudio Connect folder
|
|
46
|
+
rsconnect/
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
Package: plotcli
|
|
2
|
+
Title: Command Line Interface Plotting
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Date: 2026-02-08
|
|
5
|
+
Authors@R: c(person("Claas", "Heuer", role = c("aut", "cre"), email = "claasheuer@gmail.com"))
|
|
6
|
+
Description: The 'plotcli' package provides terminal-based plotting in R.
|
|
7
|
+
It supports colored scatter plots, line plots, bar plots, boxplots,
|
|
8
|
+
histograms, density plots, heatmaps, and more. The 'ggplotcli()' function
|
|
9
|
+
is a universal converter that renders any 'ggplot2' plot in the terminal
|
|
10
|
+
using Unicode Braille characters or ASCII. Features include support for
|
|
11
|
+
27 geom types, faceting (facet_wrap/facet_grid), automatic theme
|
|
12
|
+
detection, legends, optimized color mapping, and multiple canvas types.
|
|
13
|
+
License: LGPL-3
|
|
14
|
+
URL: https://github.com/cheuerde/plotcli
|
|
15
|
+
Encoding: UTF-8
|
|
16
|
+
VignetteBuilder: knitr
|
|
17
|
+
Depends: R6, ggplot2
|
|
18
|
+
Imports: crayon, stringr, rlang, grDevices, stats
|
|
19
|
+
Suggests:
|
|
20
|
+
testthat (>= 3.0.0),
|
|
21
|
+
knitr,
|
|
22
|
+
rmarkdown
|
|
23
|
+
NeedsCompilation: no
|
|
24
|
+
RoxygenNote: 7.3.2
|
|
25
|
+
Config/testthat/edition: 3
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Generated by roxygen2: do not edit by hand
|
|
2
|
+
|
|
3
|
+
S3method("+",plotcli)
|
|
4
|
+
S3method(cbind,plotcli)
|
|
5
|
+
S3method(rbind,plotcli)
|
|
6
|
+
export(AsciiCanvas)
|
|
7
|
+
export(BlockCanvas)
|
|
8
|
+
export(BrailleCanvas)
|
|
9
|
+
export(Canvas)
|
|
10
|
+
export(braille_dot_bit)
|
|
11
|
+
export(braille_set_dot)
|
|
12
|
+
export(bresenham)
|
|
13
|
+
export(cat_plot_matrix)
|
|
14
|
+
export(cbind_plots)
|
|
15
|
+
export(color_to_term)
|
|
16
|
+
export(create_canvas)
|
|
17
|
+
export(create_scales)
|
|
18
|
+
export(format_four_chars)
|
|
19
|
+
export(get_data_subset)
|
|
20
|
+
export(get_geom_handler)
|
|
21
|
+
export(get_term_colors)
|
|
22
|
+
export(ggplotcli)
|
|
23
|
+
export(init_color_mapping)
|
|
24
|
+
export(is_braille)
|
|
25
|
+
export(is_geom_registered)
|
|
26
|
+
export(list_registered_geoms)
|
|
27
|
+
export(make_colored)
|
|
28
|
+
export(make_unique_names)
|
|
29
|
+
export(normalize_data)
|
|
30
|
+
export(pclib)
|
|
31
|
+
export(pclibx)
|
|
32
|
+
export(pclid)
|
|
33
|
+
export(pclih)
|
|
34
|
+
export(pclil)
|
|
35
|
+
export(pclis)
|
|
36
|
+
export(pixel_to_braille)
|
|
37
|
+
export(plotcli)
|
|
38
|
+
export(plotcli_bar)
|
|
39
|
+
export(plotcli_box)
|
|
40
|
+
export(plotcli_density)
|
|
41
|
+
export(plotcli_histogram)
|
|
42
|
+
export(plotcli_line)
|
|
43
|
+
export(plotcli_options)
|
|
44
|
+
export(plotcli_scatter)
|
|
45
|
+
export(rbind_plots)
|
|
46
|
+
export(register_geom)
|
|
47
|
+
export(remove_color_codes)
|
|
48
|
+
import(R6)
|
|
49
|
+
import(ggplot2)
|
|
50
|
+
importFrom(crayon,black)
|
|
51
|
+
importFrom(crayon,blue)
|
|
52
|
+
importFrom(crayon,cyan)
|
|
53
|
+
importFrom(crayon,green)
|
|
54
|
+
importFrom(crayon,magenta)
|
|
55
|
+
importFrom(crayon,red)
|
|
56
|
+
importFrom(crayon,silver)
|
|
57
|
+
importFrom(crayon,white)
|
|
58
|
+
importFrom(crayon,yellow)
|
|
59
|
+
importFrom(grDevices,col2rgb)
|
|
60
|
+
importFrom(stats,density)
|
plotcli-original/NEWS.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# plotcli 0.3.0
|
|
2
|
+
|
|
3
|
+
## New Geom Handlers
|
|
4
|
+
|
|
5
|
+
* **11 new geom handlers** bringing total support from 16 to 27 geoms:
|
|
6
|
+
`geom_step`, `geom_abline`, `geom_ribbon`, `geom_errorbar`,
|
|
7
|
+
`geom_linerange`, `geom_pointrange`, `geom_crossbar`, `geom_rug`,
|
|
8
|
+
`geom_label`, `geom_raster`, `geom_violin`
|
|
9
|
+
|
|
10
|
+
* **Violin plots**: Proper mirrored density rendering using `violinwidth`
|
|
11
|
+
for accurate shape computation
|
|
12
|
+
|
|
13
|
+
## Bug Fixes
|
|
14
|
+
|
|
15
|
+
* Fixed division by zero when plotting constant data values
|
|
16
|
+
(e.g., all y-values identical) - both root cause fix in `get_min_max()`
|
|
17
|
+
and defensive guard in `normalize_data()` (Closes #1)
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# plotcli 0.2.0
|
|
22
|
+
|
|
23
|
+
## Major New Features
|
|
24
|
+
|
|
25
|
+
### Enhanced ggplotcli: Universal ggplot2 Converter
|
|
26
|
+
|
|
27
|
+
The `ggplotcli()` function has been completely rewritten to render any ggplot2
|
|
28
|
+
plot in the terminal:
|
|
29
|
+
|
|
30
|
+
* **16 Supported Geoms**: `geom_point`, `geom_line`, `geom_path`, `geom_bar`,
|
|
31
|
+
`geom_col`, `geom_histogram`, `geom_density`, `geom_smooth`, `geom_area`,
|
|
32
|
+
`geom_segment`, `geom_hline`, `geom_vline`, `geom_rect`, `geom_text`,
|
|
33
|
+
`geom_boxplot`, `geom_tile`
|
|
34
|
+
|
|
35
|
+
* **Legend Support**: Automatic legends for color and fill aesthetics
|
|
36
|
+
|
|
37
|
+
* **Faceting Support**: Both `facet_wrap()` and `facet_grid()` work automatically
|
|
38
|
+
|
|
39
|
+
* **Theme Auto-Detection**: Automatically respects ggplot2 themes - `theme_bw()`
|
|
40
|
+
adds borders and grids, `theme_classic()` shows only borders, etc.
|
|
41
|
+
|
|
42
|
+
* **Multiple Canvas Types**:
|
|
43
|
+
- `braille`: Highest resolution using Unicode Braille patterns (2x4 dots per character)
|
|
44
|
+
- `block`: Medium resolution using block elements
|
|
45
|
+
- `ascii`: Basic ASCII characters for maximum compatibility
|
|
46
|
+
|
|
47
|
+
* **Styling Options**: Configurable borders, grid lines, titles, subtitles,
|
|
48
|
+
captions, and axis labels
|
|
49
|
+
|
|
50
|
+
### Boxplot Rendering
|
|
51
|
+
|
|
52
|
+
* New `boxplot_style` parameter: `"ascii"` (box-drawing characters) or `"braille"`
|
|
53
|
+
* Renders whiskers, box (Q1-Q3), median line, and outliers
|
|
54
|
+
* Perfect centering of whiskers and outliers
|
|
55
|
+
|
|
56
|
+
### Optimized Color Mapping
|
|
57
|
+
|
|
58
|
+
* Intelligent color assignment minimizes repetition across groups
|
|
59
|
+
* 6 groups get 6 distinct terminal colors
|
|
60
|
+
* 8+ groups use all available colors before repeating
|
|
61
|
+
* Colors sorted by hue for visual consistency
|
|
62
|
+
|
|
63
|
+
### Canvas Abstraction Layer
|
|
64
|
+
|
|
65
|
+
New R6-based canvas system providing:
|
|
66
|
+
|
|
67
|
+
* Pixel-level drawing primitives (points, lines, rectangles, circles, polygons)
|
|
68
|
+
* Automatic Braille character composition for smooth curves
|
|
69
|
+
* Support for colored output via ANSI escape codes
|
|
70
|
+
|
|
71
|
+
### Geom Registry
|
|
72
|
+
|
|
73
|
+
Extensible system for adding custom geom handlers, making it easy to add
|
|
74
|
+
support for additional ggplot2 geoms.
|
|
75
|
+
|
|
76
|
+
### Heatmap Support
|
|
77
|
+
|
|
78
|
+
* New `geom_tile` handler for rendering heatmaps
|
|
79
|
+
* Works with continuous color scales (`scale_fill_gradient`, `scale_fill_viridis_c`, etc.)
|
|
80
|
+
* Supports faceted heatmaps with `facet_wrap()` and `facet_grid()`
|
|
81
|
+
|
|
82
|
+
## Improvements
|
|
83
|
+
|
|
84
|
+
* Improved Braille bit mapping for more accurate scatter and line plots
|
|
85
|
+
* Better color handling for multi-group aesthetics
|
|
86
|
+
* Fixed issues with quosure parsing in aesthetic mappings
|
|
87
|
+
* Fixed axis label formatting (0 now displays as "0", not "0.0e+0")
|
|
88
|
+
* Fixed border overlap issue - data no longer appears on/within borders
|
|
89
|
+
* Fixed is_braille error with ANSI color codes
|
|
90
|
+
|
|
91
|
+
## Bug Fixes (Latest)
|
|
92
|
+
|
|
93
|
+
* Fixed `geom_density` not showing distinct colors when using `fill` aesthetic
|
|
94
|
+
* Fixed heatmap legend colors not matching plot colors (legend colors now included
|
|
95
|
+
in color mapping for consistency)
|
|
96
|
+
* Fixed colors not appearing in non-interactive R sessions (Rscript) by enabling
|
|
97
|
+
crayon colors automatically on package load
|
|
98
|
+
* Fixed discrete x-axis labels showing numeric positions instead of category names
|
|
99
|
+
|
|
100
|
+
## Documentation
|
|
101
|
+
|
|
102
|
+
* Comprehensive vignette: "ggplotcli: Universal ggplot2 to Terminal Plotting"
|
|
103
|
+
* Showcase examples demonstrating maximum complexity plots
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
# plotcli 0.1.0
|
|
108
|
+
|
|
109
|
+
* Initial CRAN release
|
|
110
|
+
* Basic terminal plotting with `plotcli` R6 class
|
|
111
|
+
* Support for scatter, line, bar, and box plots
|
|
112
|
+
* Basic `ggplotcli()` function for ggplot2 conversion
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
horiz_border_char <- "\u2500"
|
|
2
|
+
vert_border_char <- "\u2502"
|
|
3
|
+
top_left_corner_char <- "\u250c"
|
|
4
|
+
top_right_corner_char <- "\u2510"
|
|
5
|
+
bottom_left_corner_char <- "\u2514"
|
|
6
|
+
bottom_right_corner_char <- "\u2518"
|
|
7
|
+
box_top_left_corner_char <- "\u2554"
|
|
8
|
+
box_top_right_corner_char <- "\u2557"
|
|
9
|
+
box_bottom_left_corner_char <- "\u255a"
|
|
10
|
+
box_bottom_right_corner_char <- "\u255d"
|
|
11
|
+
box_vert_char <- "\u2502"
|
|
12
|
+
box_horiz_char <- "\u2500"
|
|
13
|
+
full_block_char <- "\u2588"
|