kaxe 1.8.1.dev2__tar.gz → 1.8.1.dev5__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 (159) hide show
  1. {kaxe-1.8.1.dev2/src/kaxe.egg-info → kaxe-1.8.1.dev5}/PKG-INFO +39 -4
  2. kaxe-1.8.1.dev5/README.md +88 -0
  3. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/pyproject.toml +1 -1
  4. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/window.py +33 -4
  5. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/d3/plot3d.py +4 -0
  6. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/grid.py +33 -4
  7. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/viewer/client.py +11 -2
  8. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/viewer/server.py +4 -0
  9. kaxe-1.8.1.dev5/src/kaxe/viewer/window.py +597 -0
  10. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5/src/kaxe.egg-info}/PKG-INFO +39 -4
  11. kaxe-1.8.1.dev5/tests/test_viewer.py +297 -0
  12. kaxe-1.8.1.dev2/README.md +0 -53
  13. kaxe-1.8.1.dev2/src/kaxe/viewer/window.py +0 -339
  14. kaxe-1.8.1.dev2/tests/test_viewer.py +0 -140
  15. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/LICENSE +0 -0
  16. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/MANIFEST.in +0 -0
  17. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/setup.cfg +0 -0
  18. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/__init__.py +0 -0
  19. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/__main__.py +0 -0
  20. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/_require_3d.py +0 -0
  21. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/_require_viewer.py +0 -0
  22. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/chart/__init__.py +0 -0
  23. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/chart/bar.py +0 -0
  24. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/chart/box.py +0 -0
  25. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/chart/pie.py +0 -0
  26. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/chart/qqplot.py +0 -0
  27. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/cli.py +0 -0
  28. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/__init__.py +0 -0
  29. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/axis.py +0 -0
  30. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/bounds.py +0 -0
  31. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/color.py +0 -0
  32. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/backend.py +0 -0
  33. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/camera.py +0 -0
  34. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/helper.py +0 -0
  35. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/hud.py +0 -0
  36. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/objects/__init__.py +0 -0
  37. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/objects/color.py +0 -0
  38. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/objects/line.py +0 -0
  39. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/objects/point.py +0 -0
  40. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/objects/pointer.py +0 -0
  41. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/objects/triangle.py +0 -0
  42. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/openglrender.py +0 -0
  43. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/d3/translator.py +0 -0
  44. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/draw.py +0 -0
  45. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/fileloader.py +0 -0
  46. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/helper.py +0 -0
  47. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/ipython_display.py +0 -0
  48. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/legend.py +0 -0
  49. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/line.py +0 -0
  50. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/marker.py +0 -0
  51. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/palette.py +0 -0
  52. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/profiler.py +0 -0
  53. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/progress.py +0 -0
  54. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/round.py +0 -0
  55. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/shapes.py +0 -0
  56. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/styles.py +0 -0
  57. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/svg.py +0 -0
  58. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/svg_pdf.py +0 -0
  59. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/symbol.py +0 -0
  60. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/text.py +0 -0
  61. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/core/thin.py +0 -0
  62. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/data/__init__.py +0 -0
  63. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/data/excel.py +0 -0
  64. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/__init__.py +0 -0
  65. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/_lazy.py +0 -0
  66. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/__init__.py +0 -0
  67. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/arrow.py +0 -0
  68. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/bubble.py +0 -0
  69. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/contour.py +0 -0
  70. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/equation.py +0 -0
  71. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/fill.py +0 -0
  72. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/function.py +0 -0
  73. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/guide_grid.py +0 -0
  74. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/inequality.py +0 -0
  75. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/map.py +0 -0
  76. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/parameter.py +0 -0
  77. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/pillar.py +0 -0
  78. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d2/point.py +0 -0
  79. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d3/__init__.py +0 -0
  80. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d3/base.py +0 -0
  81. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d3/function.py +0 -0
  82. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d3/mesh.py +0 -0
  83. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d3/point.py +0 -0
  84. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/d3/potato.py +0 -0
  85. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/function.py +0 -0
  86. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/legend.py +0 -0
  87. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/mapdata.py +0 -0
  88. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/point.py +0 -0
  89. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/objects/text.py +0 -0
  90. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/__init__.py +0 -0
  91. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/_lazy.py +0 -0
  92. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/box.py +0 -0
  93. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/constants.py +0 -0
  94. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/d3/__init__.py +0 -0
  95. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/d3/axes.py +0 -0
  96. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/d3/geometry.py +0 -0
  97. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/d3/variants.py +0 -0
  98. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/double.py +0 -0
  99. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/empty.py +0 -0
  100. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/log.py +0 -0
  101. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/polar.py +0 -0
  102. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/standard.py +0 -0
  103. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/themes.py +0 -0
  104. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/zoom.py +0 -0
  105. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/plot/zoom_connector.py +0 -0
  106. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/project/__init__.py +0 -0
  107. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/project/codec.py +0 -0
  108. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/project/context.py +0 -0
  109. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/project/document.py +0 -0
  110. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/project/registry.py +0 -0
  111. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/project/sample.py +0 -0
  112. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/project/sampled_curve.py +0 -0
  113. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/project/serializers.py +0 -0
  114. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/project/window.py +0 -0
  115. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/__init__.py +0 -0
  116. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/__init__.py +0 -0
  117. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.bright-oblique.ttf +0 -0
  118. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.bright-roman.ttf +0 -0
  119. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.bright-semibold.ttf +0 -0
  120. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.bright-semiboldoblique.ttf +0 -0
  121. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.classical-serif-italic.ttf +0 -0
  122. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.concrete-bold.ttf +0 -0
  123. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.concrete-bolditalic.ttf +0 -0
  124. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.concrete-italic.ttf +0 -0
  125. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.concrete-roman.ttf +0 -0
  126. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-bold.ttf +0 -0
  127. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-boldoblique.ttf +0 -0
  128. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-demi-condensed-demicondensed.ttf +0 -0
  129. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-medium.ttf +0 -0
  130. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.sans-serif-oblique.ttf +0 -0
  131. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-bold.ttf +0 -0
  132. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-bolditalic.ttf +0 -0
  133. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-extra-boldslanted.ttf +0 -0
  134. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-extra-romanslanted.ttf +0 -0
  135. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-italic.ttf +0 -0
  136. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-roman.ttf +0 -0
  137. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.serif-upright-italic-uprightitalic.ttf +0 -0
  138. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-bold.ttf +0 -0
  139. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-bolditalic.ttf +0 -0
  140. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-italic.ttf +0 -0
  141. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-light.ttf +0 -0
  142. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-lightoblique.ttf +0 -0
  143. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-regular.ttf +0 -0
  144. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-italic.ttf +0 -0
  145. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/cmu.typewriter-text-variable-width-medium.ttf +0 -0
  146. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/computer-modern-family/readme.txt +0 -0
  147. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/resources/logo-small.png +0 -0
  148. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/viewer/__init__.py +0 -0
  149. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe/viewer/cli.py +0 -0
  150. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe.egg-info/SOURCES.txt +0 -0
  151. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe.egg-info/dependency_links.txt +0 -0
  152. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe.egg-info/entry_points.txt +0 -0
  153. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe.egg-info/requires.txt +0 -0
  154. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/src/kaxe.egg-info/top_level.txt +0 -0
  155. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/tests/test.py +0 -0
  156. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/tests/test2.py +0 -0
  157. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/tests/test3.py +0 -0
  158. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/tests/test_4.py +0 -0
  159. {kaxe-1.8.1.dev2 → kaxe-1.8.1.dev5}/tests/test_5.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: kaxe
3
- Version: 1.8.1.dev2
3
+ Version: 1.8.1.dev5
4
4
  Summary: A small graphing tool for functions, points, equations and more
5
5
  Author-email: Valter Yde Daugberg <valteryde@hotmail.com>
6
6
  Project-URL: Homepage, https://github.com/valteryde/kaxe
@@ -44,9 +44,9 @@ Documentation: [kaxe.readthedocs.io](https://kaxe.readthedocs.io/en/latest/)
44
44
 
45
45
  ```bash
46
46
  pip install kaxe # 2D plotting (default)
47
- pip install kaxe[3d] # add 3D plotting (OpenGL)
48
- pip install kaxe[pdf] # add PDF export
49
- pip install kaxe[3d,pdf] # 3D + PDF
47
+ pip install kaxe[viewer] # add interactive desktop viewer (pyglet)
48
+ pip install kaxe[3d] # add 3D plotting (OpenGL)
49
+ pip install kaxe[pdf] # add PDF export
50
50
  ```
51
51
 
52
52
  ## Quick example
@@ -59,10 +59,45 @@ plt.add(kaxe.Function2D(lambda x: x**2 - 4))
59
59
  plt.add(kaxe.Points2D([1, 2, 3], [1, 4, 9]))
60
60
  plt.theme(kaxe.Themes.A4Medium)
61
61
  plt.title("$x^2 - 4$")
62
+ plt.show() # streams to viewer if open, or opens system viewer
62
63
  plt.save("figure.png")
63
64
  plt.save("figure.svg")
64
65
  ```
65
66
 
67
+ ## Interactive Plot Viewer (Infinite Canvas)
68
+
69
+ Kaxe includes a dedicated, lightweight OpenGL workspace powered by [pyglet](https://pyglet.org) so you can arrange, inspect, and compare multiple plots on an infinite canvas without cluttering your desktop with preview windows.
70
+
71
+ 1. **Start the viewer** in a terminal:
72
+ ```bash
73
+ kaxe viewer
74
+ ```
75
+ 2. **Tag and show your plots**:
76
+ ```python
77
+ # Tag plots with an ID to manage them on the board:
78
+ plt1 = kaxe.Plot().id("loss").title("Training Loss")
79
+ plt1.show()
80
+
81
+ plt2 = kaxe.Plot().id("accuracy").title("Validation Accuracy")
82
+ plt2.show()
83
+ ```
84
+
85
+ When the viewer is open, `.show()` instantly streams plots to cards on your canvas. If you re-run code with the same ID, the card updates in-place and preserves previous runs as versions (`v1`, `v2`, etc.). If the viewer is closed, `.show()` automatically falls back to your operating system's default viewer.
86
+
87
+ **Canvas & Card Controls:**
88
+ * **Click & Drag on a Card**: Move that card freely across the canvas
89
+ * **Click & Drag on Empty Space**: Pan the camera across the workspace
90
+ * **Mouse Scroll**: Smooth zoom anchored to cursor
91
+ * **`[A]`**: Auto-arrange all cards in a neat row
92
+ * **`[Space]` or `[R]`**: Fit all cards on the canvas into view
93
+ * **`[1]`**: View canvas at 100% native pixel scale
94
+ * **`[←]` / `[→]`**: Cycle through versions (`v1`, `v2`, ...) of the selected card
95
+ * **`[Backspace]` / `[Delete]`**: Remove the selected card from the board
96
+ * **`[C]`** *(or Cmd/Ctrl+C)*: Copy selected plot to system clipboard
97
+ * **`[S]`** *(or Cmd/Ctrl+S)*: Save selected plot to timestamped PNG
98
+ * **`[H]`**: Toggle status & shortcuts HUD
99
+
100
+
66
101
  See the [getting started guide](https://kaxe.readthedocs.io/en/latest/pages/start.html), [recipes](https://kaxe.readthedocs.io/en/latest/pages/recipes.html), [styling guide](https://kaxe.readthedocs.io/en/latest/pages/styling.html), and [export guide](https://kaxe.readthedocs.io/en/latest/pages/export.html) for the full API.
67
102
 
68
103
  ## Goals
@@ -0,0 +1,88 @@
1
+
2
+ # Kaxe
3
+
4
+ ![BoxPlot](logo.png)
5
+
6
+ Kaxe is a lightweight, pure-Python plotting library for publication-quality figures in LaTeX documents. Create plots and charts with a simple object-oriented API, style them for A4 pages, and export to PNG or SVG.
7
+
8
+ Documentation: [kaxe.readthedocs.io](https://kaxe.readthedocs.io/en/latest/)
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ pip install kaxe # 2D plotting (default)
14
+ pip install kaxe[viewer] # add interactive desktop viewer (pyglet)
15
+ pip install kaxe[3d] # add 3D plotting (OpenGL)
16
+ pip install kaxe[pdf] # add PDF export
17
+ ```
18
+
19
+ ## Quick example
20
+
21
+ ```python
22
+ import kaxe
23
+
24
+ plt = kaxe.Plot([-5, 5, -5, 5])
25
+ plt.add(kaxe.Function2D(lambda x: x**2 - 4))
26
+ plt.add(kaxe.Points2D([1, 2, 3], [1, 4, 9]))
27
+ plt.theme(kaxe.Themes.A4Medium)
28
+ plt.title("$x^2 - 4$")
29
+ plt.show() # streams to viewer if open, or opens system viewer
30
+ plt.save("figure.png")
31
+ plt.save("figure.svg")
32
+ ```
33
+
34
+ ## Interactive Plot Viewer (Infinite Canvas)
35
+
36
+ Kaxe includes a dedicated, lightweight OpenGL workspace powered by [pyglet](https://pyglet.org) so you can arrange, inspect, and compare multiple plots on an infinite canvas without cluttering your desktop with preview windows.
37
+
38
+ 1. **Start the viewer** in a terminal:
39
+ ```bash
40
+ kaxe viewer
41
+ ```
42
+ 2. **Tag and show your plots**:
43
+ ```python
44
+ # Tag plots with an ID to manage them on the board:
45
+ plt1 = kaxe.Plot().id("loss").title("Training Loss")
46
+ plt1.show()
47
+
48
+ plt2 = kaxe.Plot().id("accuracy").title("Validation Accuracy")
49
+ plt2.show()
50
+ ```
51
+
52
+ When the viewer is open, `.show()` instantly streams plots to cards on your canvas. If you re-run code with the same ID, the card updates in-place and preserves previous runs as versions (`v1`, `v2`, etc.). If the viewer is closed, `.show()` automatically falls back to your operating system's default viewer.
53
+
54
+ **Canvas & Card Controls:**
55
+ * **Click & Drag on a Card**: Move that card freely across the canvas
56
+ * **Click & Drag on Empty Space**: Pan the camera across the workspace
57
+ * **Mouse Scroll**: Smooth zoom anchored to cursor
58
+ * **`[A]`**: Auto-arrange all cards in a neat row
59
+ * **`[Space]` or `[R]`**: Fit all cards on the canvas into view
60
+ * **`[1]`**: View canvas at 100% native pixel scale
61
+ * **`[←]` / `[→]`**: Cycle through versions (`v1`, `v2`, ...) of the selected card
62
+ * **`[Backspace]` / `[Delete]`**: Remove the selected card from the board
63
+ * **`[C]`** *(or Cmd/Ctrl+C)*: Copy selected plot to system clipboard
64
+ * **`[S]`** *(or Cmd/Ctrl+S)*: Save selected plot to timestamped PNG
65
+ * **`[H]`**: Toggle status & shortcuts HUD
66
+
67
+
68
+ See the [getting started guide](https://kaxe.readthedocs.io/en/latest/pages/start.html), [recipes](https://kaxe.readthedocs.io/en/latest/pages/recipes.html), [styling guide](https://kaxe.readthedocs.io/en/latest/pages/styling.html), and [export guide](https://kaxe.readthedocs.io/en/latest/pages/export.html) for the full API.
69
+
70
+ ## Goals
71
+
72
+ Kaxe was made to create simple, aesthetic graphs for articles, reports, and other academic work in LaTeX:
73
+
74
+ * Plots that fit the look of LaTeX documents (Computer Modern math via [fondi](https://github.com/valteryde/fondi))
75
+ * A straightforward object-oriented interface: create a window, add objects, style, save
76
+
77
+ ## Examples of plots
78
+
79
+ ![BoxPlot](tests/images/boxed.png)
80
+ ![Polar plot](tests/images/polar.png)
81
+ ![PrettyPlot3D2](tests/images/3d-function-pretty-2.png)
82
+ ![Contour grid](tests/images/contourgrid.png)
83
+ ![Contour same](tests/images/contour3d.png)
84
+ ![AllLegends](tests/images/vectorimagearrow3d.png)
85
+ ![Functions](tests/images/function.png)
86
+ ![Points](tests/images/labels.png)
87
+ ![Equations](tests/images/equation.png)
88
+ ![Globallight](tests/images/lightfunction3d.png)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "kaxe"
3
- version = "1.8.1.dev2"
3
+ version = "1.8.1.dev5"
4
4
  authors = [
5
5
  { name="Valter Yde Daugberg", email="valteryde@hotmail.com" },
6
6
  ]
@@ -647,25 +647,54 @@ class Window(AttrObject):
647
647
  logging.info('Total time to save {}s'.format(str(round(time.time() - totStartTime, 4))))
648
648
 
649
649
 
650
- def show(self):
650
+ def id(self, plot_id: str):
651
+ """Assign a persistent identifier to this plot for the Kaxe Viewer."""
652
+ self.plot_id = str(plot_id)
653
+ return self
654
+
655
+ def show(self, id: Optional[str] = None):
651
656
  """
652
- Show the current image using `Pillow.Image.Show`
657
+ Show the current image using `Pillow.Image.Show` or the Kaxe Viewer.
653
658
 
654
659
  If a cached image is available, it will be used to save the file.
655
660
  Otherwise, the image will be generated and then saved.
656
661
 
662
+ Parameters
663
+ ----------
664
+ id : str, optional
665
+ Identifier for this plot when sent to the Kaxe Viewer canvas.
666
+
657
667
  Examples
658
668
  --------
659
- >>> plt.show( )
669
+ >>> plt.show()
670
+ >>> plt.show(id="my_graph_1")
660
671
  """
672
+ if id is not None:
673
+ self.plot_id = str(id)
674
+
661
675
  data = to_png_bytes(self)
662
676
  if is_notebook():
663
677
  display_png_bytes(data)
664
- elif try_show_in_viewer(data, title=getattr(self, "titleText", "")):
678
+ elif try_show_in_viewer(
679
+ data,
680
+ title=getattr(self, "titleText", ""),
681
+ plot_id=getattr(self, "plot_id", None),
682
+ ):
665
683
  return
666
684
  else:
667
685
  Image.open(BytesIO(data)).show()
668
686
 
687
+ def open(self, id: Optional[str] = None):
688
+ """
689
+ Show the current image or stream to viewer (alias for show()).
690
+
691
+ Examples
692
+ --------
693
+ >>> plt.open()
694
+ >>> plt.open(id="my_graph_1")
695
+ """
696
+ return self.show(id=id)
697
+
669
698
  def _repr_png_(self):
670
699
  if not is_notebook():
671
700
  return None
@@ -547,6 +547,10 @@ class Plot3D(Plot3DAxesMixin, Window):
547
547
  else:
548
548
  self.save(None).show()
549
549
 
550
+ def open(self, gui=True):
551
+ """Show the current plot (alias for show())."""
552
+ return self.show(gui=gui)
553
+
550
554
  def title(self, firstAxis=None, secondAxis=None, thirdAxis=None):
551
555
  """
552
556
  Adds title to the plot.
@@ -490,25 +490,54 @@ class Grid(AttrObject):
490
490
  img.save(fname, format="png")
491
491
 
492
492
 
493
- def show(self):
493
+ def id(self, plot_id: str):
494
+ """Assign a persistent identifier to this grid for the Kaxe Viewer."""
495
+ self.plot_id = str(plot_id)
496
+ return self
497
+
498
+ def show(self, id: Optional[str] = None):
494
499
  """
495
- Show the current image using `Pillow.Image.Show`
500
+ Show the current image using `Pillow.Image.Show` or the Kaxe Viewer.
496
501
 
497
502
  If a cached image is available, it will be used to save the file.
498
503
  Otherwise, the image will be generated and then saved.
499
504
 
505
+ Parameters
506
+ ----------
507
+ id : str, optional
508
+ Identifier for this grid when sent to the Kaxe Viewer canvas.
509
+
500
510
  Examples
501
511
  --------
502
- >>> plt.show( )
512
+ >>> grid.show()
513
+ >>> grid.show(id="my_grid_1")
503
514
  """
515
+ if id is not None:
516
+ self.plot_id = str(id)
517
+
504
518
  data = to_png_bytes(self)
505
519
  if is_notebook():
506
520
  display_png_bytes(data)
507
- elif try_show_in_viewer(data, title="Grid"):
521
+ elif try_show_in_viewer(
522
+ data,
523
+ title="Grid",
524
+ plot_id=getattr(self, "plot_id", None),
525
+ ):
508
526
  return
509
527
  else:
510
528
  Image.open(BytesIO(data)).show()
511
529
 
530
+ def open(self, id: Optional[str] = None):
531
+ """
532
+ Show the current grid or stream to viewer (alias for show()).
533
+
534
+ Examples
535
+ --------
536
+ >>> grid.open()
537
+ >>> grid.open(id="my_grid_1")
538
+ """
539
+ return self.show(id=id)
540
+
512
541
  def _repr_png_(self):
513
542
  if not is_notebook():
514
543
  return None
@@ -46,6 +46,7 @@ def is_viewer_active(port: Optional[int] = None, timeout: float = 0.03) -> bool:
46
46
  def send_to_viewer(
47
47
  data: bytes,
48
48
  title: str = "",
49
+ plot_id: Optional[str] = None,
49
50
  port: Optional[int] = None,
50
51
  timeout: float = 2.0,
51
52
  ) -> bool:
@@ -58,9 +59,11 @@ def send_to_viewer(
58
59
 
59
60
  url = f"http://127.0.0.1:{port}/show"
60
61
  safe_title = urllib.parse.quote(title or "")
62
+ safe_id = urllib.parse.quote(plot_id or "")
61
63
  headers = {
62
64
  "Content-Type": "image/png",
63
65
  "X-Kaxe-Title": safe_title,
66
+ "X-Kaxe-Id": safe_id,
64
67
  }
65
68
 
66
69
  req = urllib.request.Request(url, data=data, headers=headers, method="POST")
@@ -71,12 +74,18 @@ def send_to_viewer(
71
74
  return False
72
75
 
73
76
 
74
- def try_show_in_viewer(data: bytes, title: str = "") -> bool:
77
+ def try_show_in_viewer(
78
+ data: bytes,
79
+ title: str = "",
80
+ plot_id: Optional[str] = None,
81
+ ) -> bool:
75
82
  """Convenience helper: probe port and send image if viewer is alive.
76
83
 
77
84
  Returns True if sent to viewer, False if fallback is needed.
78
85
  """
79
86
  port = get_viewer_port()
80
87
  if is_viewer_active(port):
81
- return send_to_viewer(data, title=title, port=port)
88
+ if send_to_viewer(data, title=title, plot_id=plot_id, port=port):
89
+ print("[Kaxe] Plot streamed to viewer", flush=True)
90
+ return True
82
91
  return False
@@ -40,9 +40,13 @@ class PlotRequestHandler(BaseHTTPRequestHandler):
40
40
  raw_title = self.headers.get("X-Kaxe-Title", "")
41
41
  title = urllib.parse.unquote(raw_title) if raw_title else ""
42
42
 
43
+ raw_id = self.headers.get("X-Kaxe-Id", "")
44
+ plot_id = urllib.parse.unquote(raw_id) if raw_id else ""
45
+
43
46
  item: Dict[str, Any] = {
44
47
  "data": img_bytes,
45
48
  "title": title,
49
+ "plot_id": plot_id,
46
50
  }
47
51
  self.plot_queue.put(item)
48
52