plotcli-py 0.1.0__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.
Files changed (138) hide show
  1. plotcli_py-0.1.0/CLAUDE.md +51 -0
  2. plotcli_py-0.1.0/LICENSE +21 -0
  3. plotcli_py-0.1.0/PKG-INFO +358 -0
  4. plotcli_py-0.1.0/README.md +340 -0
  5. plotcli_py-0.1.0/main.py +6 -0
  6. plotcli_py-0.1.0/plotcli-original/.Rbuildignore +18 -0
  7. plotcli_py-0.1.0/plotcli-original/.github/workflows/deploy_docs.yml +43 -0
  8. plotcli_py-0.1.0/plotcli-original/.gitignore +46 -0
  9. plotcli_py-0.1.0/plotcli-original/DESCRIPTION +25 -0
  10. plotcli_py-0.1.0/plotcli-original/NAMESPACE +60 -0
  11. plotcli_py-0.1.0/plotcli-original/NEWS.md +112 -0
  12. plotcli_py-0.1.0/plotcli-original/R/ascii_escape.r +13 -0
  13. plotcli_py-0.1.0/plotcli-original/R/canvas.r +586 -0
  14. plotcli_py-0.1.0/plotcli-original/R/class_functions.r +114 -0
  15. plotcli_py-0.1.0/plotcli-original/R/geom_registry.r +1376 -0
  16. plotcli_py-0.1.0/plotcli-original/R/ggplotcli.r +234 -0
  17. plotcli_py-0.1.0/plotcli-original/R/ggplotcli_helpers.r +1099 -0
  18. plotcli_py-0.1.0/plotcli-original/R/helper_functions.r +351 -0
  19. plotcli_py-0.1.0/plotcli-original/R/plotcli.r +963 -0
  20. plotcli_py-0.1.0/plotcli-original/R/plotcli_grid.r +1 -0
  21. plotcli_py-0.1.0/plotcli-original/R/plotcli_wrappers.r +416 -0
  22. plotcli_py-0.1.0/plotcli-original/R/zzz.r +15 -0
  23. plotcli_py-0.1.0/plotcli-original/README.md +192 -0
  24. plotcli_py-0.1.0/plotcli-original/docs/ascii.png +0 -0
  25. plotcli_py-0.1.0/plotcli-original/docs/bar.png +0 -0
  26. plotcli_py-0.1.0/plotcli-original/docs/block.png +0 -0
  27. plotcli_py-0.1.0/plotcli-original/docs/boxplot.png +0 -0
  28. plotcli_py-0.1.0/plotcli-original/docs/density.png +0 -0
  29. plotcli_py-0.1.0/plotcli-original/docs/facet.png +0 -0
  30. plotcli_py-0.1.0/plotcli-original/docs/facet_grid.png +0 -0
  31. plotcli_py-0.1.0/plotcli-original/docs/generate_png.sh +137 -0
  32. plotcli_py-0.1.0/plotcli-original/docs/heatmap.png +0 -0
  33. plotcli_py-0.1.0/plotcli-original/docs/histogram.png +0 -0
  34. plotcli_py-0.1.0/plotcli-original/docs/line.png +0 -0
  35. plotcli_py-0.1.0/plotcli-original/docs/noborder.png +0 -0
  36. plotcli_py-0.1.0/plotcli-original/docs/scatter.png +0 -0
  37. plotcli_py-0.1.0/plotcli-original/docs/showcase.R +182 -0
  38. plotcli_py-0.1.0/plotcli-original/inst/doc/ggplotcli.R +231 -0
  39. plotcli_py-0.1.0/plotcli-original/inst/doc/ggplotcli.Rmd +329 -0
  40. plotcli_py-0.1.0/plotcli-original/inst/doc/ggplotcli.html +1078 -0
  41. plotcli_py-0.1.0/plotcli-original/inst/doc/plotcli_class.R +98 -0
  42. plotcli_py-0.1.0/plotcli-original/inst/doc/plotcli_class.Rmd +121 -0
  43. plotcli_py-0.1.0/plotcli-original/inst/doc/plotcli_class.html +564 -0
  44. plotcli_py-0.1.0/plotcli-original/inst/doc/plotcli_wrappers.R +35 -0
  45. plotcli_py-0.1.0/plotcli-original/inst/doc/plotcli_wrappers.Rmd +62 -0
  46. plotcli_py-0.1.0/plotcli-original/inst/doc/plotcli_wrappers.html +546 -0
  47. plotcli_py-0.1.0/plotcli-original/man/AsciiCanvas.Rd +116 -0
  48. plotcli_py-0.1.0/plotcli-original/man/BlockCanvas.Rd +132 -0
  49. plotcli_py-0.1.0/plotcli-original/man/BrailleCanvas.Rd +146 -0
  50. plotcli_py-0.1.0/plotcli-original/man/Canvas.Rd +492 -0
  51. plotcli_py-0.1.0/plotcli-original/man/GeomRegistry.Rd +9 -0
  52. plotcli_py-0.1.0/plotcli-original/man/add_legend_to_output.Rd +12 -0
  53. plotcli_py-0.1.0/plotcli-original/man/braille_dot_bit.Rd +29 -0
  54. plotcli_py-0.1.0/plotcli-original/man/braille_set_dot.Rd +21 -0
  55. plotcli_py-0.1.0/plotcli-original/man/bresenham.Rd +27 -0
  56. plotcli_py-0.1.0/plotcli-original/man/build_plot_output.Rd +28 -0
  57. plotcli_py-0.1.0/plotcli-original/man/build_plot_output_v2.Rd +41 -0
  58. plotcli_py-0.1.0/plotcli-original/man/cat_plot_matrix.Rd +17 -0
  59. plotcli_py-0.1.0/plotcli-original/man/cbind.plotcli.Rd +19 -0
  60. plotcli_py-0.1.0/plotcli-original/man/cbind_plots.Rd +17 -0
  61. plotcli_py-0.1.0/plotcli-original/man/color_to_term.Rd +18 -0
  62. plotcli_py-0.1.0/plotcli-original/man/create_canvas.Rd +21 -0
  63. plotcli_py-0.1.0/plotcli-original/man/create_panel_scales.Rd +29 -0
  64. plotcli_py-0.1.0/plotcli-original/man/create_scales.Rd +27 -0
  65. plotcli_py-0.1.0/plotcli-original/man/dot-geom_registry.Rd +16 -0
  66. plotcli_py-0.1.0/plotcli-original/man/draw_border.Rd +12 -0
  67. plotcli_py-0.1.0/plotcli-original/man/draw_grid.Rd +12 -0
  68. plotcli_py-0.1.0/plotcli-original/man/extract_legend_info.Rd +12 -0
  69. plotcli_py-0.1.0/plotcli-original/man/extract_plot_labels.Rd +12 -0
  70. plotcli_py-0.1.0/plotcli-original/man/extract_plot_style.Rd +12 -0
  71. plotcli_py-0.1.0/plotcli-original/man/format_axis_label.Rd +18 -0
  72. plotcli_py-0.1.0/plotcli-original/man/format_four_chars.Rd +21 -0
  73. plotcli_py-0.1.0/plotcli-original/man/geom_area_handler.Rd +12 -0
  74. plotcli_py-0.1.0/plotcli-original/man/geom_bar_handler.Rd +12 -0
  75. plotcli_py-0.1.0/plotcli-original/man/geom_boxplot_handler.Rd +13 -0
  76. plotcli_py-0.1.0/plotcli-original/man/geom_density_handler.Rd +12 -0
  77. plotcli_py-0.1.0/plotcli-original/man/geom_histogram_handler.Rd +12 -0
  78. plotcli_py-0.1.0/plotcli-original/man/geom_hline_handler.Rd +12 -0
  79. plotcli_py-0.1.0/plotcli-original/man/geom_line_handler.Rd +12 -0
  80. plotcli_py-0.1.0/plotcli-original/man/geom_path_handler.Rd +12 -0
  81. plotcli_py-0.1.0/plotcli-original/man/geom_point_handler.Rd +12 -0
  82. plotcli_py-0.1.0/plotcli-original/man/geom_rect_handler.Rd +12 -0
  83. plotcli_py-0.1.0/plotcli-original/man/geom_segment_handler.Rd +12 -0
  84. plotcli_py-0.1.0/plotcli-original/man/geom_smooth_handler.Rd +12 -0
  85. plotcli_py-0.1.0/plotcli-original/man/geom_text_handler.Rd +12 -0
  86. plotcli_py-0.1.0/plotcli-original/man/geom_vline_handler.Rd +12 -0
  87. plotcli_py-0.1.0/plotcli-original/man/get_color_hue.Rd +18 -0
  88. plotcli_py-0.1.0/plotcli-original/man/get_data_subset.Rd +23 -0
  89. plotcli_py-0.1.0/plotcli-original/man/get_facet_info.Rd +18 -0
  90. plotcli_py-0.1.0/plotcli-original/man/get_geom_handler.Rd +17 -0
  91. plotcli_py-0.1.0/plotcli-original/man/get_term_colors.Rd +21 -0
  92. plotcli_py-0.1.0/plotcli-original/man/ggplotcli.Rd +83 -0
  93. plotcli_py-0.1.0/plotcli-original/man/init_color_mapping.Rd +15 -0
  94. plotcli_py-0.1.0/plotcli-original/man/is_braille.Rd +20 -0
  95. plotcli_py-0.1.0/plotcli-original/man/is_geom_registered.Rd +17 -0
  96. plotcli_py-0.1.0/plotcli-original/man/list_registered_geoms.Rd +14 -0
  97. plotcli_py-0.1.0/plotcli-original/man/make_colored.Rd +23 -0
  98. plotcli_py-0.1.0/plotcli-original/man/make_unique_names.Rd +20 -0
  99. plotcli_py-0.1.0/plotcli-original/man/normalize_data.Rd +27 -0
  100. plotcli_py-0.1.0/plotcli-original/man/pclib.Rd +48 -0
  101. plotcli_py-0.1.0/plotcli-original/man/pclibx.Rd +46 -0
  102. plotcli_py-0.1.0/plotcli-original/man/pclid.Rd +44 -0
  103. plotcli_py-0.1.0/plotcli-original/man/pclih.Rd +50 -0
  104. plotcli_py-0.1.0/plotcli-original/man/pclil.Rd +48 -0
  105. plotcli_py-0.1.0/plotcli-original/man/pclis.Rd +48 -0
  106. plotcli_py-0.1.0/plotcli-original/man/pixel_to_braille.Rd +23 -0
  107. plotcli_py-0.1.0/plotcli-original/man/plotcli.Rd +598 -0
  108. plotcli_py-0.1.0/plotcli-original/man/plotcli_bar.Rd +48 -0
  109. plotcli_py-0.1.0/plotcli-original/man/plotcli_box.Rd +46 -0
  110. plotcli_py-0.1.0/plotcli-original/man/plotcli_density.Rd +44 -0
  111. plotcli_py-0.1.0/plotcli-original/man/plotcli_histogram.Rd +50 -0
  112. plotcli_py-0.1.0/plotcli-original/man/plotcli_line.Rd +48 -0
  113. plotcli_py-0.1.0/plotcli-original/man/plotcli_options.Rd +18 -0
  114. plotcli_py-0.1.0/plotcli-original/man/plotcli_scatter.Rd +48 -0
  115. plotcli_py-0.1.0/plotcli-original/man/plus-.plotcli.Rd +19 -0
  116. plotcli_py-0.1.0/plotcli-original/man/rbind.plotcli.Rd +19 -0
  117. plotcli_py-0.1.0/plotcli-original/man/rbind_plots.Rd +17 -0
  118. plotcli_py-0.1.0/plotcli-original/man/register_geom.Rd +21 -0
  119. plotcli_py-0.1.0/plotcli-original/man/remove_color_codes.Rd +21 -0
  120. plotcli_py-0.1.0/plotcli-original/man/render_faceted_plot.Rd +25 -0
  121. plotcli_py-0.1.0/plotcli-original/man/render_single_panel.Rd +12 -0
  122. plotcli_py-0.1.0/plotcli-original/man/safe_aes_name.Rd +18 -0
  123. plotcli_py-0.1.0/plotcli-original/tests/testthat/test-new-geoms.R +136 -0
  124. plotcli_py-0.1.0/plotcli-original/tests/testthat/test-plotcli.R +69 -0
  125. plotcli_py-0.1.0/plotcli-original/tests/testthat.R +4 -0
  126. plotcli_py-0.1.0/plotcli-original/vignettes/ggplotcli.Rmd +329 -0
  127. plotcli_py-0.1.0/plotcli-original/vignettes/plotcli_class.R +98 -0
  128. plotcli_py-0.1.0/plotcli-original/vignettes/plotcli_class.Rmd +121 -0
  129. plotcli_py-0.1.0/plotcli-original/vignettes/plotcli_wrappers.R +35 -0
  130. plotcli_py-0.1.0/plotcli-original/vignettes/plotcli_wrappers.Rmd +62 -0
  131. plotcli_py-0.1.0/plotcli.egg-info/PKG-INFO +11 -0
  132. plotcli_py-0.1.0/plotcli.egg-info/SOURCES.txt +7 -0
  133. plotcli_py-0.1.0/plotcli.egg-info/dependency_links.txt +1 -0
  134. plotcli_py-0.1.0/plotcli.egg-info/entry_points.txt +3 -0
  135. plotcli_py-0.1.0/plotcli.egg-info/top_level.txt +1 -0
  136. plotcli_py-0.1.0/plotcli.py +978 -0
  137. plotcli_py-0.1.0/pyproject.toml +31 -0
  138. plotcli_py-0.1.0/uv.lock +8 -0
@@ -0,0 +1,51 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Project Overview
6
+
7
+ plotcli is a terminal plotting library for Python using Unicode Braille characters, block elements, or ASCII. It has zero dependencies and is designed for CLI workflows.
8
+
9
+ ## Commands
10
+
11
+ ```bash
12
+ # Run the CLI directly
13
+ python plotcli.py line -e "[x**2 for x in range(20)]"
14
+ python plotcli.py fn "sin(x)" 0 6.28
15
+
16
+ # Install globally with uv
17
+ uv tool install .
18
+
19
+ # Run without installing
20
+ uvx plotcli fn "sin(x)" 0 6.28
21
+
22
+ # Build distribution
23
+ uv build
24
+ ```
25
+
26
+ ## Architecture
27
+
28
+ Single-file architecture (`plotcli.py`) with these main components:
29
+
30
+ - **Canvas Classes** (lines 86-222): Three rendering backends
31
+ - `BrailleCanvas`: High-resolution (2x4 dots per cell, 8x effective resolution)
32
+ - `BlockCanvas`: Medium-resolution (half-block chars, 2x vertical resolution)
33
+ - `AsciiCanvas`: Maximum compatibility (1x1, uses `*`)
34
+
35
+ - **Plot Class** (lines 283-520): Main plotting interface
36
+ - Manages series data, axis bounds, rendering
37
+ - Uses Bresenham's algorithm for line drawing
38
+ - Auto-detects terminal size
39
+
40
+ - **Convenience Functions** (lines 525-599): `scatter()`, `line()`, `bar()`, `histogram()`, `density()`, `boxplot()`, `function_plot()`
41
+
42
+ - **Data Parsing** (lines 649-756): Handles piped data, CSV files, JSON, Python expressions
43
+
44
+ - **CLI** (lines 761-978): argparse-based interface with multiple data input methods
45
+
46
+ ## Key Patterns
47
+
48
+ - Color handling uses ANSI escape codes via `colorize()` function
49
+ - All plots normalize data to pixel coordinates via `normalize()` function
50
+ - The `Plot` class supports multiple series with different types
51
+ - Boxplot uses `compute_boxplot_stats()` for IQR-based statistics
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 plotcli contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,358 @@
1
+ Metadata-Version: 2.4
2
+ Name: plotcli-py
3
+ Version: 0.1.0
4
+ Summary: Terminal plotting using Unicode Braille/Block/ASCII. Zero dependencies. Pipe data, plot math functions, read CSV -- all from the CLI.
5
+ Project-URL: Homepage, https://github.com/wowave/plotcli-py
6
+ Project-URL: Repository, https://github.com/wowave/plotcli-py
7
+ License-Expression: MIT
8
+ License-File: LICENSE
9
+ Keywords: braille,chart,cli,graph,plot,terminal,unicode,visualization
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Environment :: Console
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Topic :: Scientific/Engineering :: Visualization
16
+ Requires-Python: >=3.8
17
+ Description-Content-Type: text/markdown
18
+
19
+ # plotcli
20
+
21
+ 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.
22
+
23
+ Inspired by the R [plotcli](https://github.com/cheuerde/plotcli) package and Julia's [UnicodePlots.jl](https://github.com/JuliaPlots/UnicodePlots.jl).
24
+
25
+ ## Install
26
+
27
+ ```bash
28
+ # With uv (recommended)
29
+ uv tool install plotcli
30
+
31
+ # With pip
32
+ pip install plotcli
33
+
34
+ # Or run directly without installing
35
+ uvx plotcli fn "sin(x)" 0 6.28
36
+ ```
37
+
38
+ ## Quick Start
39
+
40
+ ```bash
41
+ # Pipe data
42
+ echo "1 4 9 16 25 36 49 64 81 100" | plotcli line
43
+
44
+ # Plot a math function
45
+ plotcli fn "sin(x)" 0 6.28
46
+
47
+ # From a Python expression
48
+ plotcli scatter -e "[(x, x**2) for x in range(50)]"
49
+
50
+ # From a CSV file
51
+ plotcli line -f data.csv -x time -y value
52
+
53
+ # Pipe from other commands
54
+ seq 100 | awk '{print sin($1/10)}' | plotcli line
55
+ ```
56
+
57
+ ## Examples
58
+
59
+ ### Line Plot
60
+
61
+ ```bash
62
+ echo "1 4 9 16 25 36 49 64 81 100" | plotcli line --title "Squares"
63
+ ```
64
+ ```
65
+ Squares
66
+ ┌───────────────────────────────────────────────────────┐
67
+ 100 ┤ ⢀⠤⠊│
68
+ │ ⡠⠒⠁ │
69
+ 80.2 ┤ ⡠⠔⠉ │
70
+ │ ⡠⠔⠉ │
71
+ 60.4 ┤ ⢀⡠⠔⠉ │
72
+ │ ⣀⠤⠒⠁ │
73
+ y │ ⢀⡠⠔⠊ │
74
+ 40.6 ┤ ⣀⠤⠔⠊⠁ │
75
+ │ ⣀⠤⠒⠉ │
76
+ 20.8 ┤ ⣀⡠⠤⠒⠊⠉ │
77
+ │ ⢀⣀⡠⠤⠔⠒⠊⠉ │
78
+ 1 ┤⣀⣀⣀⡠⠤⠤⠤⠔⠒⠊⠉⠁ │
79
+ └───────────────────────────────────────────────────────┘
80
+ 0 2.25 4.5 6.75 9
81
+ x
82
+ ```
83
+
84
+ ### Math Functions
85
+
86
+ ```bash
87
+ plotcli fn "sin(x)" 0 6.28 --title "Sine Wave"
88
+ ```
89
+ ```
90
+ Sine Wave
91
+ ┌───────────────────────────────────────────────────────┐
92
+ 1 ┤ ⣀⠴⠒⠋⠉⠉⠙⠒⠤⣀ │
93
+ │ ⢀⡴⠋⠁ ⠈⠳⢄ │
94
+ 0.6 ┤ ⢀⡤⠋ ⠑⣄ │
95
+ │ ⢠⠊ ⠈⠱⡄ │
96
+ f 0.2 ┤ ⢀⠜⠁ ⠘⢆ │
97
+ ( │⢠⠊ ⠱⡄ │
98
+ x │⠁ ⠘⢆ ⣠⠋│
99
+ ) -0.2 ┤ ⠱⡄ ⡔⠁ │
100
+ │ ⠈⢆⡀ ⡠⠋ │
101
+ -0.6 ┤ ⠙⢄ ⣠⠚⠁ │
102
+ │ ⠑⢦⡀ ⢀⣠⠞⠁ │
103
+ -1 ┤ ⠉⠒⠤⣄⣀⣀⣠⠤⠖⠋ │
104
+ └───────────────────────────────────────────────────────┘
105
+ 0 1.57 3.14 4.71 6.28
106
+ x
107
+ ```
108
+
109
+ Built-in math: `sin`, `cos`, `tan`, `sqrt`, `log`, `exp`, `pi`, `e`, and Python's `math` module.
110
+
111
+ ```bash
112
+ plotcli fn "exp(-x/5) * cos(x*2)" 0 15 --title "Damped Oscillation"
113
+ plotcli fn "x**3 - 3*x" -3 3 --title "Cubic"
114
+ plotcli fn "log(x)" 0.1 10 --title "Logarithm"
115
+ ```
116
+
117
+ ### Histogram
118
+
119
+ ```bash
120
+ plotcli hist -e "[random.gauss(0,1) for _ in range(500)]" --title "Normal Distribution"
121
+ ```
122
+ ```
123
+ Normal Distribution
124
+ ┌───────────────────────────────────────────────────────┐
125
+ 62 ┤ ⣿⡇ │
126
+ │ ⣿⡇⢸⣿ │
127
+ 49.6 ┤ ⢰⣶ ⣿⡇⢸⣿ ⣿⡇⢰⣶ │
128
+ │ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ │
129
+ c 37.2 ┤ ⢸⣿ ⢰⣶ ⣿⡇⢸⣿ ⣿⡇⢸⣿ │
130
+ o │ ⣀⡀⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ │
131
+ u │ ⢰⣶ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ │
132
+ n 24.8 ┤ ⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣀⡀ ⣤⡄ │
133
+ t │ ⣶⡆⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇ │
134
+ 12.4 ┤ ⢰⣶ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇⢠⣤ ⣶⡆ │
135
+ │ ⣀⡀⢸⣿ ⢠⣤ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇⢸⣿ ⣿⡇⢠⣤ ⣤⡄ │
136
+ 0 ┤⣶ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⢸⣿ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣿⡇⢸⣿ ⣿⡇⢸⣿ ⣿⡇ ⣀⡀⢀⣀ ⣶│
137
+ └───────────────────────────────────────────────────────┘
138
+ -2.48 -1.06 0.36 1.78 3.2
139
+ x
140
+ ```
141
+
142
+ ### Density Plot
143
+
144
+ ```bash
145
+ plotcli density -e "[random.gauss(0,1) for _ in range(1000)]" --title "Kernel Density"
146
+ ```
147
+ ```
148
+ Kernel Density
149
+ ┌───────────────────────────────────────────────────────┐
150
+ 0.38 ┤ ⢀⠤⠒⠊⠉⠉⠢⢄ │
151
+ │ ⢰⠁ ⢣ │
152
+ 0.3 ┤ ⢠⠃ ⢣ │
153
+ d │ ⡎ ⢣ │
154
+ e 0.23 ┤ ⡜ ⢣ │
155
+ n │ ⡰⠁ ⠑⡄ │
156
+ s │ ⢀⠎ ⠘⡄ │
157
+ i 0.15 ┤ ⢀⠎ ⠱⡀ │
158
+ t │ ⢀⠎ ⢣ │
159
+ y 0.08 ┤ ⢠⠊ ⠱⡀ │
160
+ │ ⢀⠤⠒⠁ ⠈⠑⠤⡀ │
161
+ 1.7e-05 ┤⣀⣀⣀⣀⣀⣀⣀⡠⠤⠔⠊⠁ ⠈⠑⠢⠤⠤⢄⣀⣀⣀⣀⣀⣀│
162
+ └───────────────────────────────────────────────────────┘
163
+ -4.01 -2.01 -0.02 1.97 3.96
164
+ x
165
+ ```
166
+
167
+ ### Boxplot
168
+
169
+ ```bash
170
+ plotcli boxplot \
171
+ -e "[[random.gauss(m, 1+i*0.3) for _ in range(100)] for i, m in enumerate([0, 3, 7])]" \
172
+ --title "Boxplots"
173
+ ```
174
+ ```
175
+ Boxplots
176
+ ┌───────────────────────────────────────────────────────┐
177
+ 10.45 ┤ ⠈⠉⢹⠉⠉ │
178
+ │ ⢸ │
179
+ 7.83 ┤ ⡖⠒⠒⠒⠚⠒⠒⠒⠒⡆ │
180
+ │ ⢀ ⡏⠉⠉⠉⠉⠉⠉⠉⠉⡇ │
181
+ v 5.22 ┤ ⠐⠒⢲⠒⠒ ⠉⠉⠉⠉⢹⠉⠉⠉⠉⠁ │
182
+ a │ ⢸ ⢸ │
183
+ l │ ⣖⣒⣒⣒⣚⣒⣒⣒⣒⡆ ⢀⣀⣸⣀⣀ │
184
+ u 2.6 ┤ ⠒⠒⡖⠒⠂ ⠧⠤⠤⠤⢤⠤⠤⠤⠤⠇ ⠐ │
185
+ e │ ⢀⣀⣀⣀⣀⣇⣀⣀⣀⣀ ⢸ │
186
+ -0.02 ┤ ⢸⣒⣒⣒⣒⣒⣒⣒⣒⣺ ⠐⠒⠚⠒⠒ │
187
+ │ ⡇ │
188
+ -2.63 ┤ ⠉⠉⡉⠉⠁ │
189
+ └───────────────────────────────────────────────────────┘
190
+ box_1 box_2 box_3
191
+ x
192
+ ```
193
+
194
+ ### Scatter Plot
195
+
196
+ ```bash
197
+ plotcli scatter \
198
+ -e "[(x, x**1.5 + random.gauss(0,5)) for x in range(40)]" \
199
+ --title "Noisy Power Law"
200
+ ```
201
+
202
+ ### Heatmap
203
+
204
+ ```bash
205
+ plotcli heatmap \
206
+ -e "[[math.sin(r/3+c/3) for c in range(20)] for r in range(10)]" \
207
+ --title "Heatmap"
208
+ ```
209
+
210
+ ## Canvas Types
211
+
212
+ Three rendering backends with different resolution/compatibility tradeoffs:
213
+
214
+ ### Braille (default) -- highest resolution
215
+ ```bash
216
+ plotcli fn "sin(x)" 0 6.28 --canvas braille
217
+ ```
218
+ Uses Unicode Braille patterns (U+2800-U+28FF). Each character cell contains a 2x4 dot grid, giving **8x** the effective resolution of ASCII.
219
+
220
+ ### Block -- medium resolution
221
+ ```bash
222
+ plotcli fn "sin(x)" 0 6.28 --canvas block
223
+ ```
224
+ ```
225
+ Block Canvas
226
+ ┌───────────────────────────────────────────────────────┐
227
+ 1 ┤ ▄▄█▀▀▀▀█▄▄ │
228
+ │ ▄█▀ ▀▀▄ │
229
+ 0.6 ┤ ▄▀▀ █▄ │
230
+ │ ▄█▀ █▄ │
231
+ f 0.2 ┤ █▀ ▀█▄ │
232
+ ( │▄█ █▄ │
233
+ x │▀ ▀█ █▀│
234
+ ) -0.2 ┤ █▄ ▄█ │
235
+ │ ▀█ ▄█▀ │
236
+ -0.6 ┤ ▀█ ▄▄▀ │
237
+ │ ▀█▄ ▄█▀ │
238
+ -1 ┤ ▀▀█▄▄▄▄█▀▀ │
239
+ └───────────────────────────────────────────────────────┘
240
+ ```
241
+ Uses half-block characters (▀ ▄ █) for 2x vertical resolution.
242
+
243
+ ### ASCII -- maximum compatibility
244
+ ```bash
245
+ plotcli fn "sin(x)" 0 6.28 --canvas ascii
246
+ ```
247
+ ```
248
+ ASCII Canvas
249
+ ┌───────────────────────────────────────────────────────┐
250
+ 1 ┤ ******** │
251
+ │ **** **** │
252
+ 0.6 ┤ *** *** │
253
+ │ *** *** │
254
+ f 0.2 ┤ ** ** │
255
+ ( │** ** │
256
+ x │* ** **│
257
+ ) -0.2 ┤ ** ** │
258
+ │ *** *** │
259
+ -0.6 ┤ *** *** │
260
+ │ **** **** │
261
+ -1 ┤ ******** │
262
+ └───────────────────────────────────────────────────────┘
263
+ ```
264
+ Works in any terminal. Uses `*` for data points.
265
+
266
+ ## Data Input
267
+
268
+ | Method | Example |
269
+ |--------|---------|
270
+ | **Pipe values** | `echo "1 4 9 16" \| plotcli line` |
271
+ | **Pipe lines** | `seq 50 \| plotcli line` |
272
+ | **x,y pairs** | `echo -e "1,2\n3,4\n5,6" \| plotcli scatter -d ","` |
273
+ | **Expression** | `plotcli line -e "[x**2 for x in range(20)]"` |
274
+ | **Tuple list** | `plotcli scatter -e "[(x, sin(x)) for x in range(50)]"` |
275
+ | **CSV file** | `plotcli line -f data.csv -x time -y price` |
276
+ | **JSON** | `echo '[1,4,9,16]' \| plotcli line -j` |
277
+ | **Math function** | `plotcli fn "sin(x)*exp(-x/5)" 0 20` |
278
+ | **Shell pipeline** | `curl -s api \| jq '.[].value' \| plotcli line` |
279
+
280
+ ## Options
281
+
282
+ ```
283
+ -W, --width Canvas width in characters (auto-detected)
284
+ -H, --height Canvas height in characters (auto-detected)
285
+ -t, --title Plot title
286
+ --x-label X-axis label
287
+ --y-label Y-axis label
288
+ -c, --color Series color (red, green, blue, yellow, magenta, cyan, ...)
289
+ --canvas braille (default), block, or ascii
290
+ --xlim MIN MAX X-axis limits
291
+ --ylim MIN MAX Y-axis limits
292
+ --bins N Number of histogram bins
293
+ --no-legend Hide legend
294
+ -d, --delimiter Input delimiter
295
+ -j, --json Parse stdin as JSON
296
+ -e, --eval Python expression for data
297
+ -f, --file CSV/TSV file path
298
+ -x, --x-col X column name or index
299
+ -y, --y-col Y column name or index
300
+ ```
301
+
302
+ ## Use with Claude Code
303
+
304
+ plotcli is designed for AI-assisted CLI workflows. Claude Code can generate and display plots inline:
305
+
306
+ ```
307
+ > Plot a sine wave
308
+
309
+ $ plotcli fn "sin(x)" 0 6.28 --title "Sine Wave"
310
+
311
+ > Show me the distribution of file sizes in this directory
312
+
313
+ $ find . -type f -exec stat -f%z {} \; | plotcli hist --title "File Sizes" --bins 20
314
+
315
+ > Visualize the CSV data
316
+
317
+ $ plotcli scatter -f measurements.csv -x temperature -y pressure --title "T vs P"
318
+ ```
319
+
320
+ To make `plotcli` available globally for Claude Code:
321
+
322
+ ```bash
323
+ uv tool install plotcli # install globally via uv
324
+ # or
325
+ pip install plotcli # install globally via pip
326
+ ```
327
+
328
+ ## Python API
329
+
330
+ ```python
331
+ import plotcli
332
+
333
+ # Quick one-liners
334
+ plotcli.line(range(10), [x**2 for x in range(10)], title="Squares").show()
335
+ plotcli.scatter(xs, ys, title="My Data", canvas_type="braille").show()
336
+ plotcli.histogram(data, bins=20, title="Distribution").show()
337
+ plotcli.density(data, title="KDE").show()
338
+ plotcli.boxplot([group_a, group_b], names=["A", "B"]).show()
339
+ plotcli.function_plot("sin(x)*x", 0, 10).show()
340
+
341
+ # Multi-series
342
+ from plotcli import Plot
343
+ p = Plot(title="Comparison", width=60, height=15)
344
+ p.add(x1, y1, "line", color="blue", name="model")
345
+ p.add(x2, y2, "scatter", color="red", name="data")
346
+ p.show()
347
+
348
+ # Get string output (no print)
349
+ output = p.render()
350
+ ```
351
+
352
+ ## License
353
+
354
+ LGPL-3.0 (same as the original R plotcli)
355
+
356
+ ## Credits
357
+
358
+ 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).