plot3 0.6.2__tar.gz → 0.6.4__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 (81) hide show
  1. {plot3-0.6.2 → plot3-0.6.4}/PKG-INFO +21 -19
  2. {plot3-0.6.2 → plot3-0.6.4}/README.md +18 -10
  3. plot3-0.6.4/plot3/__version__.py +1 -0
  4. {plot3-0.6.2 → plot3-0.6.4}/plot3/contour.py +2 -2
  5. {plot3-0.6.2 → plot3-0.6.4}/plot3/ggplot.py +3 -3
  6. {plot3-0.6.2 → plot3-0.6.4}/plot3/static.py +5 -5
  7. {plot3-0.6.2 → plot3-0.6.4}/plot3/viewer.py +16 -7
  8. {plot3-0.6.2 → plot3-0.6.4}/plot3.egg-info/PKG-INFO +21 -19
  9. {plot3-0.6.2 → plot3-0.6.4}/plot3.egg-info/requires.txt +1 -10
  10. {plot3-0.6.2 → plot3-0.6.4}/pyproject.toml +1 -4
  11. {plot3-0.6.2 → plot3-0.6.4}/tests/test_contour.py +1 -1
  12. {plot3-0.6.2 → plot3-0.6.4}/tests/test_static_save.py +2 -2
  13. plot3-0.6.2/plot3/__version__.py +0 -1
  14. {plot3-0.6.2 → plot3-0.6.4}/LICENSE +0 -0
  15. {plot3-0.6.2 → plot3-0.6.4}/plot3/__init__.py +0 -0
  16. {plot3-0.6.2 → plot3-0.6.4}/plot3/aesexpr.py +0 -0
  17. {plot3-0.6.2 → plot3-0.6.4}/plot3/build.py +0 -0
  18. {plot3-0.6.2 → plot3-0.6.4}/plot3/calculus.py +0 -0
  19. {plot3-0.6.2 → plot3-0.6.4}/plot3/compose.py +0 -0
  20. {plot3-0.6.2 → plot3-0.6.4}/plot3/craft.py +0 -0
  21. {plot3-0.6.2 → plot3-0.6.4}/plot3/encode.py +0 -0
  22. {plot3-0.6.2 → plot3-0.6.4}/plot3/expr.py +0 -0
  23. {plot3-0.6.2 → plot3-0.6.4}/plot3/flip.py +0 -0
  24. {plot3-0.6.2 → plot3-0.6.4}/plot3/function.py +0 -0
  25. {plot3-0.6.2 → plot3-0.6.4}/plot3/geoms.py +0 -0
  26. {plot3-0.6.2 → plot3-0.6.4}/plot3/io.py +0 -0
  27. {plot3-0.6.2 → plot3-0.6.4}/plot3/jupyter.py +0 -0
  28. {plot3-0.6.2 → plot3-0.6.4}/plot3/latexin.py +0 -0
  29. {plot3-0.6.2 → plot3-0.6.4}/plot3/masking.py +0 -0
  30. {plot3-0.6.2 → plot3-0.6.4}/plot3/mathtext.py +0 -0
  31. {plot3-0.6.2 → plot3-0.6.4}/plot3/payload.py +0 -0
  32. {plot3-0.6.2 → plot3-0.6.4}/plot3/remote.py +0 -0
  33. {plot3-0.6.2 → plot3-0.6.4}/plot3/scales.py +0 -0
  34. {plot3-0.6.2 → plot3-0.6.4}/plot3/scaling.py +0 -0
  35. {plot3-0.6.2 → plot3-0.6.4}/plot3/special.py +0 -0
  36. {plot3-0.6.2 → plot3-0.6.4}/plot3/stat2d.py +0 -0
  37. {plot3-0.6.2 → plot3-0.6.4}/plot3/stats3d.py +0 -0
  38. {plot3-0.6.2 → plot3-0.6.4}/plot3/table.py +0 -0
  39. {plot3-0.6.2 → plot3-0.6.4}/plot3/themes.py +0 -0
  40. {plot3-0.6.2 → plot3-0.6.4}/plot3.egg-info/SOURCES.txt +0 -0
  41. {plot3-0.6.2 → plot3-0.6.4}/plot3.egg-info/dependency_links.txt +0 -0
  42. {plot3-0.6.2 → plot3-0.6.4}/plot3.egg-info/top_level.txt +0 -0
  43. {plot3-0.6.2 → plot3-0.6.4}/setup.cfg +0 -0
  44. {plot3-0.6.2 → plot3-0.6.4}/tests/test_2d_density.py +0 -0
  45. {plot3-0.6.2 → plot3-0.6.4}/tests/test_3d.py +0 -0
  46. {plot3-0.6.2 → plot3-0.6.4}/tests/test_animation.py +0 -0
  47. {plot3-0.6.2 → plot3-0.6.4}/tests/test_annotate.py +0 -0
  48. {plot3-0.6.2 → plot3-0.6.4}/tests/test_api_public.py +0 -0
  49. {plot3-0.6.2 → plot3-0.6.4}/tests/test_array_backend.py +0 -0
  50. {plot3-0.6.2 → plot3-0.6.4}/tests/test_arrow.py +0 -0
  51. {plot3-0.6.2 → plot3-0.6.4}/tests/test_build_contract.py +0 -0
  52. {plot3-0.6.2 → plot3-0.6.4}/tests/test_everyday_ggplot2.py +0 -0
  53. {plot3-0.6.2 → plot3-0.6.4}/tests/test_expr.py +0 -0
  54. {plot3-0.6.2 → plot3-0.6.4}/tests/test_facets_compose.py +0 -0
  55. {plot3-0.6.2 → plot3-0.6.4}/tests/test_geom_function.py +0 -0
  56. {plot3-0.6.2 → plot3-0.6.4}/tests/test_geoms_ds.py +0 -0
  57. {plot3-0.6.2 → plot3-0.6.4}/tests/test_ggplot2_extras2.py +0 -0
  58. {plot3-0.6.2 → plot3-0.6.4}/tests/test_ggplot2_parity.py +0 -0
  59. {plot3-0.6.2 → plot3-0.6.4}/tests/test_ggplot_extras.py +0 -0
  60. {plot3-0.6.2 → plot3-0.6.4}/tests/test_grammar.py +0 -0
  61. {plot3-0.6.2 → plot3-0.6.4}/tests/test_latex_input.py +0 -0
  62. {plot3-0.6.2 → plot3-0.6.4}/tests/test_lidar_scene.py +0 -0
  63. {plot3-0.6.2 → plot3-0.6.4}/tests/test_masking.py +0 -0
  64. {plot3-0.6.2 → plot3-0.6.4}/tests/test_math_layers.py +0 -0
  65. {plot3-0.6.2 → plot3-0.6.4}/tests/test_mathtext.py +0 -0
  66. {plot3-0.6.2 → plot3-0.6.4}/tests/test_payload.py +0 -0
  67. {plot3-0.6.2 → plot3-0.6.4}/tests/test_payload_display.py +0 -0
  68. {plot3-0.6.2 → plot3-0.6.4}/tests/test_point_cloud.py +0 -0
  69. {plot3-0.6.2 → plot3-0.6.4}/tests/test_r_oracle_parity.py +0 -0
  70. {plot3-0.6.2 → plot3-0.6.4}/tests/test_readme.py +0 -0
  71. {plot3-0.6.2 → plot3-0.6.4}/tests/test_remote_bridge.py +0 -0
  72. {plot3-0.6.2 → plot3-0.6.4}/tests/test_review_fixes.py +0 -0
  73. {plot3-0.6.2 → plot3-0.6.4}/tests/test_save_menu.py +0 -0
  74. {plot3-0.6.2 → plot3-0.6.4}/tests/test_scales_api.py +0 -0
  75. {plot3-0.6.2 → plot3-0.6.4}/tests/test_scales_themes.py +0 -0
  76. {plot3-0.6.2 → plot3-0.6.4}/tests/test_special.py +0 -0
  77. {plot3-0.6.2 → plot3-0.6.4}/tests/test_stat2d.py +0 -0
  78. {plot3-0.6.2 → plot3-0.6.4}/tests/test_stats_semantic.py +0 -0
  79. {plot3-0.6.2 → plot3-0.6.4}/tests/test_step3_geoms.py +0 -0
  80. {plot3-0.6.2 → plot3-0.6.4}/tests/test_table_backends.py +0 -0
  81. {plot3-0.6.2 → plot3-0.6.4}/tests/test_titles_theme.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plot3
3
- Version: 0.6.2
3
+ Version: 0.6.4
4
4
  Summary: ggplot2 grammar of graphics for Python: interactive WebGL figures and journal-ready PNG, SVG, and PDF
5
5
  Author: Rigoberto Leyva Salmeron
6
6
  License-Expression: MIT
@@ -17,18 +17,12 @@ Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: numpy>=1.24
19
19
  Requires-Dist: pandas>=2.0
20
- Provides-Extra: fast
21
- Requires-Dist: contourpy>=1.0; extra == "fast"
20
+ Provides-Extra: pdf
21
+ Requires-Dist: cairosvg>=2.7; extra == "pdf"
22
22
  Provides-Extra: dev
23
23
  Requires-Dist: pytest>=7.0; extra == "dev"
24
24
  Requires-Dist: polars>=1.0; extra == "dev"
25
25
  Requires-Dist: contourpy>=1.0; extra == "dev"
26
- Provides-Extra: jupyter
27
- Requires-Dist: ipython>=8.0; extra == "jupyter"
28
- Provides-Extra: polars
29
- Requires-Dist: polars>=1.0; extra == "polars"
30
- Provides-Extra: export
31
- Requires-Dist: cairosvg>=2.7; extra == "export"
32
26
  Dynamic: license-file
33
27
 
34
28
  # plot3
@@ -57,7 +51,7 @@ in the notebook and save as journal-ready PNG, SVG, or PDF.
57
51
  </table>
58
52
 
59
53
  ```bash
60
- pip install "plot3[jupyter,export]"
54
+ pip install plot3
61
55
  ```
62
56
 
63
57
  Contents: [Plot an equation](#plot-an-equation) ·
@@ -279,27 +273,35 @@ In notebooks, bare column names work as in R: `aes(x=dose, y=response)`.
279
273
  ## Install
280
274
 
281
275
  ```bash
282
- pip install "plot3[jupyter,export]"
276
+ pip install plot3
283
277
  ```
284
278
 
285
279
  Python 3.10 or newer; NumPy and pandas are the only required packages.
280
+ Notebooks, pandas, and Polars tables work with no extras.
286
281
 
287
- | Extra | Adds |
288
- |---|---|
289
- | `export` | `cairosvg`: PNG with real fonts and PDF. Needs the Cairo C library (`brew install cairo`, `apt install libcairo2`). SVG needs nothing. |
290
- | `fast` | `contourpy`: faster implicit-curve contours (matplotlib users have it) |
291
- | `jupyter` | IPython integration (bare column names, `%plot3`) |
292
- | `polars` | Polars tables |
282
+ For PDF, and PNG with real fonts, add cairosvg and the Cairo library. SVG
283
+ needs neither.
284
+
285
+ ```bash
286
+ pip install cairosvg
287
+ ```
288
+
289
+ ```bash
290
+ brew install cairo
291
+ ```
292
+
293
+ (`apt install libcairo2` on Debian and Ubuntu.) `pip install "plot3[pdf]"`
294
+ installs plot3 and cairosvg together.
293
295
 
294
296
  The latest unreleased code installs from GitHub with
295
- `pip install "plot3[jupyter,export] @ git+https://github.com/rleyvasal/plot3"`.
297
+ `pip install "plot3 @ git+https://github.com/rleyvasal/plot3"`.
296
298
 
297
299
  ## Development
298
300
 
299
301
  ```bash
300
302
  git clone https://github.com/rleyvasal/plot3 && cd plot3
301
303
  python3 -m venv .venv && source .venv/bin/activate
302
- pip install -e ".[dev,jupyter,export]"
304
+ pip install -e ".[dev]"
303
305
  pytest -q # includes every example in this README and docs/reference.md
304
306
  python examples/showcase_2d.py # 2D gallery in the browser
305
307
  python examples/showcase_3d.py # 3D gallery
@@ -24,7 +24,7 @@ in the notebook and save as journal-ready PNG, SVG, or PDF.
24
24
  </table>
25
25
 
26
26
  ```bash
27
- pip install "plot3[jupyter,export]"
27
+ pip install plot3
28
28
  ```
29
29
 
30
30
  Contents: [Plot an equation](#plot-an-equation) ·
@@ -246,27 +246,35 @@ In notebooks, bare column names work as in R: `aes(x=dose, y=response)`.
246
246
  ## Install
247
247
 
248
248
  ```bash
249
- pip install "plot3[jupyter,export]"
249
+ pip install plot3
250
250
  ```
251
251
 
252
252
  Python 3.10 or newer; NumPy and pandas are the only required packages.
253
+ Notebooks, pandas, and Polars tables work with no extras.
253
254
 
254
- | Extra | Adds |
255
- |---|---|
256
- | `export` | `cairosvg`: PNG with real fonts and PDF. Needs the Cairo C library (`brew install cairo`, `apt install libcairo2`). SVG needs nothing. |
257
- | `fast` | `contourpy`: faster implicit-curve contours (matplotlib users have it) |
258
- | `jupyter` | IPython integration (bare column names, `%plot3`) |
259
- | `polars` | Polars tables |
255
+ For PDF, and PNG with real fonts, add cairosvg and the Cairo library. SVG
256
+ needs neither.
257
+
258
+ ```bash
259
+ pip install cairosvg
260
+ ```
261
+
262
+ ```bash
263
+ brew install cairo
264
+ ```
265
+
266
+ (`apt install libcairo2` on Debian and Ubuntu.) `pip install "plot3[pdf]"`
267
+ installs plot3 and cairosvg together.
260
268
 
261
269
  The latest unreleased code installs from GitHub with
262
- `pip install "plot3[jupyter,export] @ git+https://github.com/rleyvasal/plot3"`.
270
+ `pip install "plot3 @ git+https://github.com/rleyvasal/plot3"`.
263
271
 
264
272
  ## Development
265
273
 
266
274
  ```bash
267
275
  git clone https://github.com/rleyvasal/plot3 && cd plot3
268
276
  python3 -m venv .venv && source .venv/bin/activate
269
- pip install -e ".[dev,jupyter,export]"
277
+ pip install -e ".[dev]"
270
278
  pytest -q # includes every example in this README and docs/reference.md
271
279
  python examples/showcase_2d.py # 2D gallery in the browser
272
280
  python examples/showcase_3d.py # 3D gallery
@@ -0,0 +1 @@
1
+ __version__ = "0.6.4"
@@ -115,7 +115,7 @@ def _backend_name() -> str:
115
115
  if _load_contourpy() is None:
116
116
  raise ValueError(
117
117
  "PLOT3_CONTOUR_BACKEND=contourpy but contourpy>=1.0 is not "
118
- "installed. Install it with: pip install plot3[fast]"
118
+ "installed. Install it with: pip install contourpy"
119
119
  )
120
120
  return "contourpy"
121
121
  if _load_contourpy() is None:
@@ -346,7 +346,7 @@ def _contour_contourpy(
346
346
  if contourpy is None:
347
347
  raise ValueError(
348
348
  "PLOT3_CONTOUR_BACKEND=contourpy but contourpy>=1.0 is not "
349
- "installed. Install it with: pip install plot3[fast]"
349
+ "installed. Install it with: pip install contourpy"
350
350
  )
351
351
  masked = np.ma.masked_invalid(np.asarray(field, dtype=np.float64))
352
352
  generator = contourpy.contour_generator(
@@ -517,7 +517,7 @@ class ggplot:
517
517
  suffix writes the standalone HTML viewer. ``width`` and ``height``
518
518
  are pixels unless ``units`` is ``"in"``, ``"cm"``, or ``"mm"``.
519
519
  ``dpi`` is the PNG resolution for a physical size (default 300).
520
- PDF needs ``plot3[export]`` and the Cairo C library. ``.svg``
520
+ PDF needs cairosvg and the Cairo C library. ``.svg``
521
521
  needs neither.
522
522
  """
523
523
  suffix = Path(path).suffix.lower()
@@ -683,8 +683,8 @@ def ggsave(
683
683
  """Save ``plot``.
684
684
 
685
685
  ``ggsave("fig.png", p)`` and ``ggsave("fig.svg", p)`` write a static
686
- image. ``ggsave("fig.pdf", p)`` writes a PDF when ``plot3[export]`` is
687
- installed. That extra also needs the Cairo C library; ``.svg`` writes
686
+ image. ``ggsave("fig.pdf", p)`` writes a PDF when cairosvg is
687
+ installed (``plot3[pdf]``). It also needs the Cairo C library; ``.svg`` writes
688
688
  the same drawing with no extra dependencies. Any other suffix,
689
689
  including ``.html``, writes the standalone viewer. The plot and the
690
690
  filename can be passed in either order.
@@ -2,7 +2,7 @@
2
2
 
3
3
  PNG, SVG, and PDF replay one list of drawing commands. SVG is text.
4
4
  PNG and PDF are that same SVG rendered by cairosvg when the optional
5
- ``plot3[export]`` extra is installed, so the three files share one
5
+ ``plot3[pdf]`` extra (cairosvg) is installed, so the three files share one
6
6
  drawing and one font. That extra needs the Cairo C library as well as
7
7
  the Python package (``libcairo2``, or the GTK runtime on Windows).
8
8
  Without cairosvg, PNG falls back to a zlib RGB file and a built-in
@@ -42,7 +42,7 @@ _UNIT_INCH = {
42
42
  }
43
43
  _EXPORT_HINT = (
44
44
  "ggsave() needs the Cairo C library to write PDF with a journal font. "
45
- "Install the Python extra with: pip install 'plot3[export]'. "
45
+ "Install it with: pip install cairosvg. "
46
46
  "Windows and minimal Linux images also need the Cairo library itself "
47
47
  "(for example the libcairo2 package, or the GTK runtime). "
48
48
  "ggsave('fig.svg', plot) writes the same drawing with no extra dependencies."
@@ -196,8 +196,8 @@ def save_static(
196
196
  ``"cm"`` and ``"mm"``) with ``dpi`` (default 300) sets a physical
197
197
  page. Layout stays in CSS pixels (96 per inch) so type keeps its
198
198
  size, and cairosvg rasterizes that SVG at ``dpi``. PDF and a
199
- journal-font PNG need the Cairo C library (``pip install
200
- 'plot3[export]'``). ``.svg`` needs nothing extra.
199
+ journal-font PNG need cairosvg and the Cairo C library (``pip install
200
+ cairosvg``). ``.svg`` needs nothing extra.
201
201
  """
202
202
  path = Path(path)
203
203
  suffix = path.suffix.lower()
@@ -251,7 +251,7 @@ def save_static(
251
251
  if fallback:
252
252
  print(
253
253
  "plot3: PNG used the built-in font. "
254
- "pip install 'plot3[export]' for Helvetica."
254
+ "pip install cairosvg for Helvetica."
255
255
  )
256
256
  return str(path)
257
257
 
@@ -55,6 +55,9 @@ body{display:flex;flex-direction:column}
55
55
  #legend .sz-block{clear:both;padding-top:6px}
56
56
  #legend .bub{display:inline-block;border-radius:50%;box-sizing:border-box;flex:none;
57
57
  border:1px solid rgba(0,0,0,.35)}
58
+ #legend.docked{display:flex!important;flex-wrap:wrap;align-items:center;column-gap:14px;row-gap:0;line-height:1.5}
59
+ #legend.docked .sz-block{display:flex;flex-wrap:wrap;align-items:center;column-gap:10px;padding-top:0;clear:none}
60
+ #legend.docked .sz{margin:0}
58
61
  #player{display:none;flex:none;align-items:center;flex-wrap:wrap;gap:8px;padding:4px 10px 8px;max-width:100%;box-sizing:border-box}
59
62
  #player button{font:inherit;padding:3px 10px;border-radius:5px;cursor:pointer}
60
63
  #player #play-range{flex:1;min-width:80px}
@@ -345,19 +348,25 @@ function showLegendBox() {
345
348
  legEl.style.border = '1px solid ' + T.grid;
346
349
  legEl.style.color = T.ink2;
347
350
  }
351
+ // Height the docked legend takes at the bottom; the plot shrinks by it.
352
+ let legendReserve = 0;
348
353
  function placeLegend() {
349
- if (!legEl || legEl.style.display === 'none' || legEl.dataset.docked === '1') return;
354
+ legendReserve = 0;
355
+ if (!legEl || legEl.style.display === 'none') return;
350
356
  const figH = figEl.clientHeight || 0;
351
357
  if (figH < 40) return;
352
- // A key taller than the panel covers the curve. Sit it under the axes.
353
- if (legEl.offsetHeight > figH * 0.40) {
358
+ // A key taller than the panel covers the data (a short notebook output).
359
+ // Lay it out in rows under the axes, and keep that room free.
360
+ if (legEl.dataset.docked !== '1' && legEl.offsetHeight > figH * 0.40) {
354
361
  legEl.dataset.docked = '1';
362
+ legEl.classList.add('docked');
355
363
  legEl.style.top = 'auto';
356
- legEl.style.bottom = '8px';
364
+ legEl.style.bottom = '6px';
357
365
  legEl.style.left = '8px';
358
366
  legEl.style.right = '8px';
359
367
  legEl.style.maxWidth = 'none';
360
368
  }
369
+ if (legEl.dataset.docked === '1') legendReserve = legEl.offsetHeight + 8;
361
370
  }
362
371
  const LEGEND_GLYPH = { circle: '●', triangle: '▲', square: '■', diamond: '◆', plus: '+', cross: '×' };
363
372
  // Legend keys: a square, the point's symbol, or a short (dashed) line.
@@ -2036,7 +2045,7 @@ if (!S.is3d) {
2036
2045
  function layout() {
2037
2046
  placeLegend();
2038
2047
  W = Math.max(50, figEl.clientWidth - M.l - M.r);
2039
- H = Math.max(50, figEl.clientHeight - M.t - M.b);
2048
+ H = Math.max(50, figEl.clientHeight - M.t - M.b - legendReserve);
2040
2049
  if (equalAspect) applyEqual();
2041
2050
  host.style.left = M.l + 'px'; host.style.top = M.t + 'px';
2042
2051
  renderer.setSize(W, H);
@@ -2741,7 +2750,7 @@ if (!S.is3d) {
2741
2750
 
2742
2751
  function layout() {
2743
2752
  placeLegend();
2744
- const w = Math.max(figEl.clientWidth, 1), h = Math.max(figEl.clientHeight, 1);
2753
+ const w = Math.max(figEl.clientWidth, 1), h = Math.max(figEl.clientHeight - legendReserve, 1);
2745
2754
  renderer.setSize(w, h);
2746
2755
  cam.aspect = w / h;
2747
2756
  cam.updateProjectionMatrix();
@@ -2763,7 +2772,7 @@ if (!S.is3d) {
2763
2772
  const touches = (a, b, air) => a[0] - air < b[0] + b[2] && b[0] - air < a[0] + a[2] &&
2764
2773
  a[1] - air < b[1] + b[3] && b[1] - air < a[1] + a[3];
2765
2774
  function declutterTicks() {
2766
- const w = Math.max(figEl.clientWidth, 1), h = Math.max(figEl.clientHeight, 1);
2775
+ const w = Math.max(figEl.clientWidth, 1), h = Math.max(figEl.clientHeight - legendReserve, 1);
2767
2776
  const placed = [];
2768
2777
  for (const marks of tickSprites) {
2769
2778
  if (!marks.length) continue;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plot3
3
- Version: 0.6.2
3
+ Version: 0.6.4
4
4
  Summary: ggplot2 grammar of graphics for Python: interactive WebGL figures and journal-ready PNG, SVG, and PDF
5
5
  Author: Rigoberto Leyva Salmeron
6
6
  License-Expression: MIT
@@ -17,18 +17,12 @@ Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: numpy>=1.24
19
19
  Requires-Dist: pandas>=2.0
20
- Provides-Extra: fast
21
- Requires-Dist: contourpy>=1.0; extra == "fast"
20
+ Provides-Extra: pdf
21
+ Requires-Dist: cairosvg>=2.7; extra == "pdf"
22
22
  Provides-Extra: dev
23
23
  Requires-Dist: pytest>=7.0; extra == "dev"
24
24
  Requires-Dist: polars>=1.0; extra == "dev"
25
25
  Requires-Dist: contourpy>=1.0; extra == "dev"
26
- Provides-Extra: jupyter
27
- Requires-Dist: ipython>=8.0; extra == "jupyter"
28
- Provides-Extra: polars
29
- Requires-Dist: polars>=1.0; extra == "polars"
30
- Provides-Extra: export
31
- Requires-Dist: cairosvg>=2.7; extra == "export"
32
26
  Dynamic: license-file
33
27
 
34
28
  # plot3
@@ -57,7 +51,7 @@ in the notebook and save as journal-ready PNG, SVG, or PDF.
57
51
  </table>
58
52
 
59
53
  ```bash
60
- pip install "plot3[jupyter,export]"
54
+ pip install plot3
61
55
  ```
62
56
 
63
57
  Contents: [Plot an equation](#plot-an-equation) ·
@@ -279,27 +273,35 @@ In notebooks, bare column names work as in R: `aes(x=dose, y=response)`.
279
273
  ## Install
280
274
 
281
275
  ```bash
282
- pip install "plot3[jupyter,export]"
276
+ pip install plot3
283
277
  ```
284
278
 
285
279
  Python 3.10 or newer; NumPy and pandas are the only required packages.
280
+ Notebooks, pandas, and Polars tables work with no extras.
286
281
 
287
- | Extra | Adds |
288
- |---|---|
289
- | `export` | `cairosvg`: PNG with real fonts and PDF. Needs the Cairo C library (`brew install cairo`, `apt install libcairo2`). SVG needs nothing. |
290
- | `fast` | `contourpy`: faster implicit-curve contours (matplotlib users have it) |
291
- | `jupyter` | IPython integration (bare column names, `%plot3`) |
292
- | `polars` | Polars tables |
282
+ For PDF, and PNG with real fonts, add cairosvg and the Cairo library. SVG
283
+ needs neither.
284
+
285
+ ```bash
286
+ pip install cairosvg
287
+ ```
288
+
289
+ ```bash
290
+ brew install cairo
291
+ ```
292
+
293
+ (`apt install libcairo2` on Debian and Ubuntu.) `pip install "plot3[pdf]"`
294
+ installs plot3 and cairosvg together.
293
295
 
294
296
  The latest unreleased code installs from GitHub with
295
- `pip install "plot3[jupyter,export] @ git+https://github.com/rleyvasal/plot3"`.
297
+ `pip install "plot3 @ git+https://github.com/rleyvasal/plot3"`.
296
298
 
297
299
  ## Development
298
300
 
299
301
  ```bash
300
302
  git clone https://github.com/rleyvasal/plot3 && cd plot3
301
303
  python3 -m venv .venv && source .venv/bin/activate
302
- pip install -e ".[dev,jupyter,export]"
304
+ pip install -e ".[dev]"
303
305
  pytest -q # includes every example in this README and docs/reference.md
304
306
  python examples/showcase_2d.py # 2D gallery in the browser
305
307
  python examples/showcase_3d.py # 3D gallery
@@ -6,14 +6,5 @@ pytest>=7.0
6
6
  polars>=1.0
7
7
  contourpy>=1.0
8
8
 
9
- [export]
9
+ [pdf]
10
10
  cairosvg>=2.7
11
-
12
- [fast]
13
- contourpy>=1.0
14
-
15
- [jupyter]
16
- ipython>=8.0
17
-
18
- [polars]
19
- polars>=1.0
@@ -25,11 +25,8 @@ dependencies = [
25
25
  ]
26
26
 
27
27
  [project.optional-dependencies]
28
- fast = ["contourpy>=1.0"]
28
+ pdf = ["cairosvg>=2.7"]
29
29
  dev = ["pytest>=7.0", "polars>=1.0", "contourpy>=1.0"]
30
- jupyter = ["ipython>=8.0"]
31
- polars = ["polars>=1.0"]
32
- export = ["cairosvg>=2.7"]
33
30
 
34
31
  [project.urls]
35
32
  Homepage = "https://github.com/rleyvasal/plot3"
@@ -265,7 +265,7 @@ def test_version_floor_and_backend_selection(monkeypatch):
265
265
  assert _backend_name() == "numpy"
266
266
  monkeypatch.setenv("PLOT3_CONTOUR_BACKEND", "contourpy")
267
267
  _reset_contour_backend()
268
- with pytest.raises(ValueError, match=r"plot3\[fast\]"):
268
+ with pytest.raises(ValueError, match=r"pip install contourpy"):
269
269
  _contour_lines(np.linspace(-1, 1, 4), np.linspace(-1, 1, 4), np.zeros((4, 4)), 0.0)
270
270
 
271
271
  fake = types.ModuleType("contourpy")
@@ -438,7 +438,7 @@ def test_inches_and_dpi_set_the_png_page(tmp_path, monkeypatch, capsys):
438
438
  rgb = _read_png(path)
439
439
  assert rgb.shape == (1200, 2100, 3)
440
440
  assert tuple(rgb[0, 0]) == (255, 255, 255)
441
- assert "plot3[export]" in capsys.readouterr().out
441
+ assert "pip install cairosvg" in capsys.readouterr().out
442
442
 
443
443
  cm = tmp_path / "cm.png"
444
444
  ggsave(cm, fig, width=2.54, height=2.54, units="cm", dpi=100)
@@ -466,7 +466,7 @@ def test_pdf_without_cairosvg_names_the_extra(tmp_path, monkeypatch):
466
466
  from plot3 import static
467
467
 
468
468
  monkeypatch.setattr(static, "_load_cairosvg", lambda: None)
469
- with pytest.raises(RuntimeError, match=r"plot3\[export\]") as caught:
469
+ with pytest.raises(RuntimeError, match=r"pip install cairosvg") as caught:
470
470
  ggsave(tmp_path / "fig.pdf", _curve())
471
471
  message = str(caught.value)
472
472
  assert "Cairo" in message
@@ -1 +0,0 @@
1
- __version__ = "0.6.2"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes