vispy 0.15.0__cp313-cp313-macosx_11_0_arm64.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.

Potentially problematic release.


This version of vispy might be problematic. Click here for more details.

Files changed (521) hide show
  1. vispy/__init__.py +33 -0
  2. vispy/app/__init__.py +15 -0
  3. vispy/app/_default_app.py +76 -0
  4. vispy/app/_detect_eventloop.py +148 -0
  5. vispy/app/application.py +263 -0
  6. vispy/app/backends/__init__.py +52 -0
  7. vispy/app/backends/_egl.py +264 -0
  8. vispy/app/backends/_glfw.py +513 -0
  9. vispy/app/backends/_jupyter_rfb.py +278 -0
  10. vispy/app/backends/_offscreen_util.py +121 -0
  11. vispy/app/backends/_osmesa.py +235 -0
  12. vispy/app/backends/_pyglet.py +451 -0
  13. vispy/app/backends/_pyqt4.py +36 -0
  14. vispy/app/backends/_pyqt5.py +36 -0
  15. vispy/app/backends/_pyqt6.py +40 -0
  16. vispy/app/backends/_pyside.py +37 -0
  17. vispy/app/backends/_pyside2.py +52 -0
  18. vispy/app/backends/_pyside6.py +53 -0
  19. vispy/app/backends/_qt.py +1003 -0
  20. vispy/app/backends/_sdl2.py +444 -0
  21. vispy/app/backends/_template.py +244 -0
  22. vispy/app/backends/_test.py +8 -0
  23. vispy/app/backends/_tk.py +800 -0
  24. vispy/app/backends/_wx.py +476 -0
  25. vispy/app/backends/tests/__init__.py +0 -0
  26. vispy/app/backends/tests/test_offscreen_util.py +52 -0
  27. vispy/app/backends/tests/test_rfb.py +77 -0
  28. vispy/app/base.py +294 -0
  29. vispy/app/canvas.py +828 -0
  30. vispy/app/qt.py +92 -0
  31. vispy/app/tests/__init__.py +0 -0
  32. vispy/app/tests/qt-designer.ui +58 -0
  33. vispy/app/tests/test_app.py +442 -0
  34. vispy/app/tests/test_backends.py +164 -0
  35. vispy/app/tests/test_canvas.py +122 -0
  36. vispy/app/tests/test_context.py +92 -0
  37. vispy/app/tests/test_qt.py +47 -0
  38. vispy/app/tests/test_simultaneous.py +134 -0
  39. vispy/app/timer.py +174 -0
  40. vispy/color/__init__.py +17 -0
  41. vispy/color/_color_dict.py +193 -0
  42. vispy/color/color_array.py +447 -0
  43. vispy/color/color_space.py +181 -0
  44. vispy/color/colormap.py +1213 -0
  45. vispy/color/tests/__init__.py +0 -0
  46. vispy/color/tests/test_color.py +378 -0
  47. vispy/conftest.py +12 -0
  48. vispy/ext/__init__.py +0 -0
  49. vispy/ext/cocoapy.py +1522 -0
  50. vispy/ext/cubehelix.py +138 -0
  51. vispy/ext/egl.py +375 -0
  52. vispy/ext/fontconfig.py +118 -0
  53. vispy/ext/gdi32plus.py +206 -0
  54. vispy/ext/osmesa.py +105 -0
  55. vispy/geometry/__init__.py +23 -0
  56. vispy/geometry/_triangulation_debugger.py +171 -0
  57. vispy/geometry/calculations.py +162 -0
  58. vispy/geometry/curves.py +399 -0
  59. vispy/geometry/generation.py +643 -0
  60. vispy/geometry/isocurve.py +175 -0
  61. vispy/geometry/isosurface.py +465 -0
  62. vispy/geometry/meshdata.py +700 -0
  63. vispy/geometry/normals.py +78 -0
  64. vispy/geometry/parametric.py +56 -0
  65. vispy/geometry/polygon.py +137 -0
  66. vispy/geometry/rect.py +210 -0
  67. vispy/geometry/tests/__init__.py +0 -0
  68. vispy/geometry/tests/test_calculations.py +23 -0
  69. vispy/geometry/tests/test_generation.py +56 -0
  70. vispy/geometry/tests/test_meshdata.py +106 -0
  71. vispy/geometry/tests/test_triangulation.py +594 -0
  72. vispy/geometry/torusknot.py +142 -0
  73. vispy/geometry/triangulation.py +876 -0
  74. vispy/gloo/__init__.py +56 -0
  75. vispy/gloo/buffer.py +505 -0
  76. vispy/gloo/context.py +272 -0
  77. vispy/gloo/framebuffer.py +257 -0
  78. vispy/gloo/gl/__init__.py +234 -0
  79. vispy/gloo/gl/_constants.py +332 -0
  80. vispy/gloo/gl/_es2.py +986 -0
  81. vispy/gloo/gl/_gl2.py +1365 -0
  82. vispy/gloo/gl/_proxy.py +499 -0
  83. vispy/gloo/gl/_pyopengl2.py +362 -0
  84. vispy/gloo/gl/dummy.py +24 -0
  85. vispy/gloo/gl/es2.py +62 -0
  86. vispy/gloo/gl/gl2.py +98 -0
  87. vispy/gloo/gl/glplus.py +168 -0
  88. vispy/gloo/gl/pyopengl2.py +97 -0
  89. vispy/gloo/gl/tests/__init__.py +0 -0
  90. vispy/gloo/gl/tests/test_basics.py +282 -0
  91. vispy/gloo/gl/tests/test_functionality.py +568 -0
  92. vispy/gloo/gl/tests/test_names.py +246 -0
  93. vispy/gloo/gl/tests/test_use.py +71 -0
  94. vispy/gloo/glir.py +1824 -0
  95. vispy/gloo/globject.py +101 -0
  96. vispy/gloo/preprocessor.py +67 -0
  97. vispy/gloo/program.py +543 -0
  98. vispy/gloo/tests/__init__.py +0 -0
  99. vispy/gloo/tests/test_buffer.py +558 -0
  100. vispy/gloo/tests/test_context.py +119 -0
  101. vispy/gloo/tests/test_framebuffer.py +195 -0
  102. vispy/gloo/tests/test_glir.py +307 -0
  103. vispy/gloo/tests/test_globject.py +35 -0
  104. vispy/gloo/tests/test_program.py +302 -0
  105. vispy/gloo/tests/test_texture.py +732 -0
  106. vispy/gloo/tests/test_use_gloo.py +187 -0
  107. vispy/gloo/tests/test_util.py +60 -0
  108. vispy/gloo/tests/test_wrappers.py +261 -0
  109. vispy/gloo/texture.py +1046 -0
  110. vispy/gloo/util.py +129 -0
  111. vispy/gloo/wrappers.py +762 -0
  112. vispy/glsl/__init__.py +42 -0
  113. vispy/glsl/antialias/antialias.glsl +7 -0
  114. vispy/glsl/antialias/cap-butt.glsl +31 -0
  115. vispy/glsl/antialias/cap-round.glsl +29 -0
  116. vispy/glsl/antialias/cap-square.glsl +30 -0
  117. vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
  118. vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
  119. vispy/glsl/antialias/cap.glsl +67 -0
  120. vispy/glsl/antialias/caps.glsl +67 -0
  121. vispy/glsl/antialias/filled.glsl +50 -0
  122. vispy/glsl/antialias/outline.glsl +40 -0
  123. vispy/glsl/antialias/stroke.glsl +43 -0
  124. vispy/glsl/arrowheads/angle.glsl +99 -0
  125. vispy/glsl/arrowheads/arrowheads.frag +60 -0
  126. vispy/glsl/arrowheads/arrowheads.glsl +12 -0
  127. vispy/glsl/arrowheads/arrowheads.vert +83 -0
  128. vispy/glsl/arrowheads/curved.glsl +48 -0
  129. vispy/glsl/arrowheads/inhibitor.glsl +26 -0
  130. vispy/glsl/arrowheads/stealth.glsl +46 -0
  131. vispy/glsl/arrowheads/triangle.glsl +97 -0
  132. vispy/glsl/arrowheads/util.glsl +13 -0
  133. vispy/glsl/arrows/angle-30.glsl +12 -0
  134. vispy/glsl/arrows/angle-60.glsl +12 -0
  135. vispy/glsl/arrows/angle-90.glsl +12 -0
  136. vispy/glsl/arrows/arrow.frag +39 -0
  137. vispy/glsl/arrows/arrow.vert +49 -0
  138. vispy/glsl/arrows/arrows.glsl +17 -0
  139. vispy/glsl/arrows/common.glsl +187 -0
  140. vispy/glsl/arrows/curved.glsl +63 -0
  141. vispy/glsl/arrows/stealth.glsl +50 -0
  142. vispy/glsl/arrows/triangle-30.glsl +12 -0
  143. vispy/glsl/arrows/triangle-60.glsl +12 -0
  144. vispy/glsl/arrows/triangle-90.glsl +12 -0
  145. vispy/glsl/arrows/util.glsl +98 -0
  146. vispy/glsl/build_spatial_filters.py +660 -0
  147. vispy/glsl/collections/agg-fast-path.frag +20 -0
  148. vispy/glsl/collections/agg-fast-path.vert +78 -0
  149. vispy/glsl/collections/agg-glyph.frag +60 -0
  150. vispy/glsl/collections/agg-glyph.vert +33 -0
  151. vispy/glsl/collections/agg-marker.frag +35 -0
  152. vispy/glsl/collections/agg-marker.vert +48 -0
  153. vispy/glsl/collections/agg-path.frag +55 -0
  154. vispy/glsl/collections/agg-path.vert +166 -0
  155. vispy/glsl/collections/agg-point.frag +21 -0
  156. vispy/glsl/collections/agg-point.vert +35 -0
  157. vispy/glsl/collections/agg-segment.frag +32 -0
  158. vispy/glsl/collections/agg-segment.vert +75 -0
  159. vispy/glsl/collections/marker.frag +38 -0
  160. vispy/glsl/collections/marker.vert +48 -0
  161. vispy/glsl/collections/raw-path.frag +15 -0
  162. vispy/glsl/collections/raw-path.vert +24 -0
  163. vispy/glsl/collections/raw-point.frag +14 -0
  164. vispy/glsl/collections/raw-point.vert +31 -0
  165. vispy/glsl/collections/raw-segment.frag +18 -0
  166. vispy/glsl/collections/raw-segment.vert +26 -0
  167. vispy/glsl/collections/raw-triangle.frag +13 -0
  168. vispy/glsl/collections/raw-triangle.vert +26 -0
  169. vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
  170. vispy/glsl/collections/sdf-glyph.frag +80 -0
  171. vispy/glsl/collections/sdf-glyph.vert +59 -0
  172. vispy/glsl/collections/tick-labels.vert +71 -0
  173. vispy/glsl/colormaps/autumn.glsl +20 -0
  174. vispy/glsl/colormaps/blues.glsl +20 -0
  175. vispy/glsl/colormaps/color-space.glsl +17 -0
  176. vispy/glsl/colormaps/colormaps.glsl +24 -0
  177. vispy/glsl/colormaps/cool.glsl +20 -0
  178. vispy/glsl/colormaps/fire.glsl +21 -0
  179. vispy/glsl/colormaps/gray.glsl +20 -0
  180. vispy/glsl/colormaps/greens.glsl +20 -0
  181. vispy/glsl/colormaps/hot.glsl +22 -0
  182. vispy/glsl/colormaps/ice.glsl +20 -0
  183. vispy/glsl/colormaps/icefire.glsl +23 -0
  184. vispy/glsl/colormaps/parse.py +40 -0
  185. vispy/glsl/colormaps/reds.glsl +20 -0
  186. vispy/glsl/colormaps/spring.glsl +20 -0
  187. vispy/glsl/colormaps/summer.glsl +20 -0
  188. vispy/glsl/colormaps/user.glsl +22 -0
  189. vispy/glsl/colormaps/util.glsl +41 -0
  190. vispy/glsl/colormaps/wheel.glsl +21 -0
  191. vispy/glsl/colormaps/winter.glsl +20 -0
  192. vispy/glsl/lines/agg.frag +320 -0
  193. vispy/glsl/lines/agg.vert +241 -0
  194. vispy/glsl/markers/arrow.glsl +12 -0
  195. vispy/glsl/markers/asterisk.glsl +16 -0
  196. vispy/glsl/markers/chevron.glsl +14 -0
  197. vispy/glsl/markers/clover.glsl +20 -0
  198. vispy/glsl/markers/club.glsl +31 -0
  199. vispy/glsl/markers/cross.glsl +17 -0
  200. vispy/glsl/markers/diamond.glsl +12 -0
  201. vispy/glsl/markers/disc.glsl +9 -0
  202. vispy/glsl/markers/ellipse.glsl +67 -0
  203. vispy/glsl/markers/hbar.glsl +9 -0
  204. vispy/glsl/markers/heart.glsl +15 -0
  205. vispy/glsl/markers/infinity.glsl +15 -0
  206. vispy/glsl/markers/marker-sdf.frag +74 -0
  207. vispy/glsl/markers/marker-sdf.vert +41 -0
  208. vispy/glsl/markers/marker.frag +36 -0
  209. vispy/glsl/markers/marker.vert +46 -0
  210. vispy/glsl/markers/markers.glsl +24 -0
  211. vispy/glsl/markers/pin.glsl +18 -0
  212. vispy/glsl/markers/ring.glsl +11 -0
  213. vispy/glsl/markers/spade.glsl +28 -0
  214. vispy/glsl/markers/square.glsl +10 -0
  215. vispy/glsl/markers/tag.glsl +11 -0
  216. vispy/glsl/markers/triangle.glsl +14 -0
  217. vispy/glsl/markers/vbar.glsl +9 -0
  218. vispy/glsl/math/circle-through-2-points.glsl +30 -0
  219. vispy/glsl/math/constants.glsl +48 -0
  220. vispy/glsl/math/double.glsl +114 -0
  221. vispy/glsl/math/functions.glsl +20 -0
  222. vispy/glsl/math/point-to-line-distance.glsl +31 -0
  223. vispy/glsl/math/point-to-line-projection.glsl +29 -0
  224. vispy/glsl/math/signed-line-distance.glsl +27 -0
  225. vispy/glsl/math/signed-segment-distance.glsl +30 -0
  226. vispy/glsl/misc/regular-grid.frag +244 -0
  227. vispy/glsl/misc/spatial-filters.frag +1407 -0
  228. vispy/glsl/misc/viewport-NDC.glsl +20 -0
  229. vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
  230. vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
  231. vispy/glsl/transforms/hammer.glsl +44 -0
  232. vispy/glsl/transforms/identity.glsl +6 -0
  233. vispy/glsl/transforms/identity_forward.glsl +23 -0
  234. vispy/glsl/transforms/identity_inverse.glsl +23 -0
  235. vispy/glsl/transforms/linear-scale.glsl +127 -0
  236. vispy/glsl/transforms/log-scale.glsl +126 -0
  237. vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
  238. vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
  239. vispy/glsl/transforms/panzoom.glsl +10 -0
  240. vispy/glsl/transforms/polar.glsl +41 -0
  241. vispy/glsl/transforms/position.glsl +44 -0
  242. vispy/glsl/transforms/power-scale.glsl +139 -0
  243. vispy/glsl/transforms/projection.glsl +7 -0
  244. vispy/glsl/transforms/pvm.glsl +13 -0
  245. vispy/glsl/transforms/rotate.glsl +45 -0
  246. vispy/glsl/transforms/trackball.glsl +15 -0
  247. vispy/glsl/transforms/translate.glsl +35 -0
  248. vispy/glsl/transforms/transverse_mercator.glsl +38 -0
  249. vispy/glsl/transforms/viewport-clipping.glsl +14 -0
  250. vispy/glsl/transforms/viewport-transform.glsl +16 -0
  251. vispy/glsl/transforms/viewport.glsl +50 -0
  252. vispy/glsl/transforms/x.glsl +24 -0
  253. vispy/glsl/transforms/y.glsl +19 -0
  254. vispy/glsl/transforms/z.glsl +14 -0
  255. vispy/io/__init__.py +20 -0
  256. vispy/io/_data/spatial-filters.npy +0 -0
  257. vispy/io/datasets.py +94 -0
  258. vispy/io/image.py +231 -0
  259. vispy/io/mesh.py +122 -0
  260. vispy/io/stl.py +167 -0
  261. vispy/io/tests/__init__.py +0 -0
  262. vispy/io/tests/test_image.py +47 -0
  263. vispy/io/tests/test_io.py +121 -0
  264. vispy/io/wavefront.py +350 -0
  265. vispy/plot/__init__.py +36 -0
  266. vispy/plot/fig.py +58 -0
  267. vispy/plot/plotwidget.py +522 -0
  268. vispy/plot/tests/__init__.py +0 -0
  269. vispy/plot/tests/test_plot.py +46 -0
  270. vispy/scene/__init__.py +43 -0
  271. vispy/scene/cameras/__init__.py +27 -0
  272. vispy/scene/cameras/_base.py +38 -0
  273. vispy/scene/cameras/arcball.py +105 -0
  274. vispy/scene/cameras/base_camera.py +551 -0
  275. vispy/scene/cameras/fly.py +474 -0
  276. vispy/scene/cameras/magnify.py +163 -0
  277. vispy/scene/cameras/panzoom.py +311 -0
  278. vispy/scene/cameras/perspective.py +338 -0
  279. vispy/scene/cameras/tests/__init__.py +0 -0
  280. vispy/scene/cameras/tests/test_cameras.py +27 -0
  281. vispy/scene/cameras/tests/test_link.py +53 -0
  282. vispy/scene/cameras/tests/test_perspective.py +122 -0
  283. vispy/scene/cameras/turntable.py +183 -0
  284. vispy/scene/canvas.py +639 -0
  285. vispy/scene/events.py +85 -0
  286. vispy/scene/node.py +644 -0
  287. vispy/scene/subscene.py +20 -0
  288. vispy/scene/tests/__init__.py +0 -0
  289. vispy/scene/tests/test_canvas.py +119 -0
  290. vispy/scene/tests/test_node.py +142 -0
  291. vispy/scene/tests/test_visuals.py +141 -0
  292. vispy/scene/visuals.py +276 -0
  293. vispy/scene/widgets/__init__.py +18 -0
  294. vispy/scene/widgets/anchor.py +25 -0
  295. vispy/scene/widgets/axis.py +88 -0
  296. vispy/scene/widgets/colorbar.py +176 -0
  297. vispy/scene/widgets/console.py +351 -0
  298. vispy/scene/widgets/grid.py +509 -0
  299. vispy/scene/widgets/label.py +50 -0
  300. vispy/scene/widgets/tests/__init__.py +0 -0
  301. vispy/scene/widgets/tests/test_colorbar.py +47 -0
  302. vispy/scene/widgets/viewbox.py +199 -0
  303. vispy/scene/widgets/widget.py +478 -0
  304. vispy/testing/__init__.py +51 -0
  305. vispy/testing/_runners.py +448 -0
  306. vispy/testing/_testing.py +416 -0
  307. vispy/testing/image_tester.py +494 -0
  308. vispy/testing/rendered_array_tester.py +85 -0
  309. vispy/testing/tests/__init__.py +0 -0
  310. vispy/testing/tests/test_testing.py +20 -0
  311. vispy/util/__init__.py +32 -0
  312. vispy/util/bunch.py +15 -0
  313. vispy/util/check_environment.py +57 -0
  314. vispy/util/config.py +490 -0
  315. vispy/util/dpi/__init__.py +19 -0
  316. vispy/util/dpi/_linux.py +69 -0
  317. vispy/util/dpi/_quartz.py +26 -0
  318. vispy/util/dpi/_win32.py +34 -0
  319. vispy/util/dpi/tests/__init__.py +0 -0
  320. vispy/util/dpi/tests/test_dpi.py +16 -0
  321. vispy/util/eq.py +41 -0
  322. vispy/util/event.py +774 -0
  323. vispy/util/fetching.py +276 -0
  324. vispy/util/filter.py +44 -0
  325. vispy/util/fonts/__init__.py +14 -0
  326. vispy/util/fonts/_freetype.py +73 -0
  327. vispy/util/fonts/_quartz.py +192 -0
  328. vispy/util/fonts/_triage.py +36 -0
  329. vispy/util/fonts/_vispy_fonts.py +20 -0
  330. vispy/util/fonts/_win32.py +105 -0
  331. vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
  332. vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
  333. vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
  334. vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
  335. vispy/util/fonts/tests/__init__.py +0 -0
  336. vispy/util/fonts/tests/test_font.py +45 -0
  337. vispy/util/fourier.py +69 -0
  338. vispy/util/frozen.py +25 -0
  339. vispy/util/gallery_scraper.py +268 -0
  340. vispy/util/keys.py +91 -0
  341. vispy/util/logs.py +358 -0
  342. vispy/util/osmesa_gl.py +17 -0
  343. vispy/util/profiler.py +135 -0
  344. vispy/util/ptime.py +16 -0
  345. vispy/util/quaternion.py +229 -0
  346. vispy/util/svg/__init__.py +18 -0
  347. vispy/util/svg/base.py +20 -0
  348. vispy/util/svg/color.py +219 -0
  349. vispy/util/svg/element.py +51 -0
  350. vispy/util/svg/geometry.py +478 -0
  351. vispy/util/svg/group.py +66 -0
  352. vispy/util/svg/length.py +81 -0
  353. vispy/util/svg/number.py +25 -0
  354. vispy/util/svg/path.py +332 -0
  355. vispy/util/svg/shapes.py +57 -0
  356. vispy/util/svg/style.py +59 -0
  357. vispy/util/svg/svg.py +40 -0
  358. vispy/util/svg/transform.py +223 -0
  359. vispy/util/svg/transformable.py +28 -0
  360. vispy/util/svg/viewport.py +73 -0
  361. vispy/util/tests/__init__.py +0 -0
  362. vispy/util/tests/test_config.py +58 -0
  363. vispy/util/tests/test_docstring_parameters.py +123 -0
  364. vispy/util/tests/test_emitter_group.py +262 -0
  365. vispy/util/tests/test_event_emitter.py +743 -0
  366. vispy/util/tests/test_fourier.py +35 -0
  367. vispy/util/tests/test_gallery_scraper.py +112 -0
  368. vispy/util/tests/test_import.py +127 -0
  369. vispy/util/tests/test_key.py +22 -0
  370. vispy/util/tests/test_logging.py +45 -0
  371. vispy/util/tests/test_run.py +14 -0
  372. vispy/util/tests/test_transforms.py +42 -0
  373. vispy/util/tests/test_vispy.py +48 -0
  374. vispy/util/transforms.py +201 -0
  375. vispy/util/wrappers.py +155 -0
  376. vispy/version.py +21 -0
  377. vispy/visuals/__init__.py +50 -0
  378. vispy/visuals/_scalable_textures.py +487 -0
  379. vispy/visuals/axis.py +678 -0
  380. vispy/visuals/border.py +208 -0
  381. vispy/visuals/box.py +79 -0
  382. vispy/visuals/collections/__init__.py +30 -0
  383. vispy/visuals/collections/agg_fast_path_collection.py +219 -0
  384. vispy/visuals/collections/agg_path_collection.py +197 -0
  385. vispy/visuals/collections/agg_point_collection.py +52 -0
  386. vispy/visuals/collections/agg_segment_collection.py +142 -0
  387. vispy/visuals/collections/array_list.py +401 -0
  388. vispy/visuals/collections/base_collection.py +482 -0
  389. vispy/visuals/collections/collection.py +253 -0
  390. vispy/visuals/collections/path_collection.py +23 -0
  391. vispy/visuals/collections/point_collection.py +19 -0
  392. vispy/visuals/collections/polygon_collection.py +25 -0
  393. vispy/visuals/collections/raw_path_collection.py +119 -0
  394. vispy/visuals/collections/raw_point_collection.py +113 -0
  395. vispy/visuals/collections/raw_polygon_collection.py +77 -0
  396. vispy/visuals/collections/raw_segment_collection.py +112 -0
  397. vispy/visuals/collections/raw_triangle_collection.py +78 -0
  398. vispy/visuals/collections/segment_collection.py +19 -0
  399. vispy/visuals/collections/triangle_collection.py +16 -0
  400. vispy/visuals/collections/util.py +168 -0
  401. vispy/visuals/colorbar.py +699 -0
  402. vispy/visuals/cube.py +41 -0
  403. vispy/visuals/ellipse.py +162 -0
  404. vispy/visuals/filters/__init__.py +10 -0
  405. vispy/visuals/filters/base_filter.py +242 -0
  406. vispy/visuals/filters/clipper.py +60 -0
  407. vispy/visuals/filters/clipping_planes.py +122 -0
  408. vispy/visuals/filters/color.py +181 -0
  409. vispy/visuals/filters/markers.py +28 -0
  410. vispy/visuals/filters/mesh.py +801 -0
  411. vispy/visuals/filters/picking.py +60 -0
  412. vispy/visuals/filters/tests/__init__.py +3 -0
  413. vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
  414. vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
  415. vispy/visuals/glsl/__init__.py +1 -0
  416. vispy/visuals/glsl/antialiasing.py +133 -0
  417. vispy/visuals/glsl/color.py +63 -0
  418. vispy/visuals/graphs/__init__.py +1 -0
  419. vispy/visuals/graphs/graph.py +240 -0
  420. vispy/visuals/graphs/layouts/__init__.py +55 -0
  421. vispy/visuals/graphs/layouts/circular.py +49 -0
  422. vispy/visuals/graphs/layouts/force_directed.py +211 -0
  423. vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
  424. vispy/visuals/graphs/layouts/random.py +52 -0
  425. vispy/visuals/graphs/tests/__init__.py +1 -0
  426. vispy/visuals/graphs/tests/test_layouts.py +139 -0
  427. vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
  428. vispy/visuals/graphs/util.py +120 -0
  429. vispy/visuals/gridlines.py +161 -0
  430. vispy/visuals/gridmesh.py +98 -0
  431. vispy/visuals/histogram.py +58 -0
  432. vispy/visuals/image.py +701 -0
  433. vispy/visuals/image_complex.py +130 -0
  434. vispy/visuals/infinite_line.py +199 -0
  435. vispy/visuals/instanced_mesh.py +152 -0
  436. vispy/visuals/isocurve.py +213 -0
  437. vispy/visuals/isoline.py +241 -0
  438. vispy/visuals/isosurface.py +113 -0
  439. vispy/visuals/line/__init__.py +6 -0
  440. vispy/visuals/line/arrow.py +289 -0
  441. vispy/visuals/line/dash_atlas.py +90 -0
  442. vispy/visuals/line/line.py +545 -0
  443. vispy/visuals/line_plot.py +135 -0
  444. vispy/visuals/linear_region.py +199 -0
  445. vispy/visuals/markers.py +819 -0
  446. vispy/visuals/mesh.py +373 -0
  447. vispy/visuals/mesh_normals.py +159 -0
  448. vispy/visuals/plane.py +54 -0
  449. vispy/visuals/polygon.py +145 -0
  450. vispy/visuals/rectangle.py +196 -0
  451. vispy/visuals/regular_polygon.py +56 -0
  452. vispy/visuals/scrolling_lines.py +197 -0
  453. vispy/visuals/shaders/__init__.py +17 -0
  454. vispy/visuals/shaders/compiler.py +206 -0
  455. vispy/visuals/shaders/expression.py +99 -0
  456. vispy/visuals/shaders/function.py +788 -0
  457. vispy/visuals/shaders/multiprogram.py +145 -0
  458. vispy/visuals/shaders/parsing.py +140 -0
  459. vispy/visuals/shaders/program.py +161 -0
  460. vispy/visuals/shaders/shader_object.py +162 -0
  461. vispy/visuals/shaders/tests/__init__.py +0 -0
  462. vispy/visuals/shaders/tests/test_function.py +486 -0
  463. vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
  464. vispy/visuals/shaders/tests/test_parsing.py +57 -0
  465. vispy/visuals/shaders/variable.py +272 -0
  466. vispy/visuals/spectrogram.py +169 -0
  467. vispy/visuals/sphere.py +80 -0
  468. vispy/visuals/surface_plot.py +192 -0
  469. vispy/visuals/tests/__init__.py +0 -0
  470. vispy/visuals/tests/test_arrows.py +109 -0
  471. vispy/visuals/tests/test_axis.py +120 -0
  472. vispy/visuals/tests/test_collections.py +15 -0
  473. vispy/visuals/tests/test_colorbar.py +179 -0
  474. vispy/visuals/tests/test_colormap.py +97 -0
  475. vispy/visuals/tests/test_ellipse.py +122 -0
  476. vispy/visuals/tests/test_gridlines.py +30 -0
  477. vispy/visuals/tests/test_histogram.py +24 -0
  478. vispy/visuals/tests/test_image.py +392 -0
  479. vispy/visuals/tests/test_image_complex.py +36 -0
  480. vispy/visuals/tests/test_infinite_line.py +53 -0
  481. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  482. vispy/visuals/tests/test_isosurface.py +22 -0
  483. vispy/visuals/tests/test_linear_region.py +152 -0
  484. vispy/visuals/tests/test_markers.py +54 -0
  485. vispy/visuals/tests/test_mesh.py +261 -0
  486. vispy/visuals/tests/test_mesh_normals.py +218 -0
  487. vispy/visuals/tests/test_polygon.py +112 -0
  488. vispy/visuals/tests/test_rectangle.py +163 -0
  489. vispy/visuals/tests/test_regular_polygon.py +111 -0
  490. vispy/visuals/tests/test_scalable_textures.py +196 -0
  491. vispy/visuals/tests/test_sdf.py +73 -0
  492. vispy/visuals/tests/test_spectrogram.py +42 -0
  493. vispy/visuals/tests/test_surface_plot.py +57 -0
  494. vispy/visuals/tests/test_text.py +95 -0
  495. vispy/visuals/tests/test_volume.py +542 -0
  496. vispy/visuals/tests/test_windbarb.py +33 -0
  497. vispy/visuals/text/__init__.py +7 -0
  498. vispy/visuals/text/_sdf_cpu.cpython-313-darwin.so +0 -0
  499. vispy/visuals/text/_sdf_cpu.pyx +112 -0
  500. vispy/visuals/text/_sdf_gpu.py +316 -0
  501. vispy/visuals/text/text.py +675 -0
  502. vispy/visuals/transforms/__init__.py +34 -0
  503. vispy/visuals/transforms/_util.py +191 -0
  504. vispy/visuals/transforms/base_transform.py +233 -0
  505. vispy/visuals/transforms/chain.py +300 -0
  506. vispy/visuals/transforms/interactive.py +98 -0
  507. vispy/visuals/transforms/linear.py +564 -0
  508. vispy/visuals/transforms/nonlinear.py +398 -0
  509. vispy/visuals/transforms/tests/__init__.py +0 -0
  510. vispy/visuals/transforms/tests/test_transforms.py +243 -0
  511. vispy/visuals/transforms/transform_system.py +339 -0
  512. vispy/visuals/tube.py +173 -0
  513. vispy/visuals/visual.py +923 -0
  514. vispy/visuals/volume.py +1366 -0
  515. vispy/visuals/windbarb.py +291 -0
  516. vispy/visuals/xyz_axis.py +34 -0
  517. vispy-0.15.0.dist-info/METADATA +243 -0
  518. vispy-0.15.0.dist-info/RECORD +521 -0
  519. vispy-0.15.0.dist-info/WHEEL +6 -0
  520. vispy-0.15.0.dist-info/licenses/LICENSE.txt +36 -0
  521. vispy-0.15.0.dist-info/top_level.txt +1 -0
vispy/visuals/axis.py ADDED
@@ -0,0 +1,678 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -----------------------------------------------------------------------------
3
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
4
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
5
+ # -----------------------------------------------------------------------------
6
+
7
+ import math
8
+
9
+ import numpy as np
10
+
11
+ from .visual import CompoundVisual, updating_property
12
+ from .line import LineVisual
13
+ from .text import TextVisual
14
+
15
+ # XXX TODO list (see code, plus):
16
+ # 1. Automated tick direction?
17
+ # 2. Expand to 3D (only 2D supported currently)
18
+ # 3. Input validation
19
+ # 4. Property support
20
+ # 5. Reactivity to resizing (current tick lengths grow/shrink w/zoom)
21
+ # 6. Improve tick label naming (str(x) is not good) and tick selection
22
+
23
+
24
+ class AxisVisual(CompoundVisual):
25
+ """Axis visual
26
+
27
+ Parameters
28
+ ----------
29
+ pos : array
30
+ Co-ordinates of start and end of the axis.
31
+ domain : tuple
32
+ The data values at the beginning and end of the axis, used for tick
33
+ labels. i.e. (5, 10) means the axis starts at 5 and ends at 10. Default
34
+ is (0, 1).
35
+ tick_direction : array
36
+ The tick direction to use (in document coordinates).
37
+ scale_type : str
38
+ The type of scale. For now only 'linear' is supported.
39
+ axis_color : tuple
40
+ RGBA values for the axis colour. Default is black.
41
+ tick_color : tuple
42
+ RGBA values for the tick colours. The colour for the major and minor
43
+ ticks is currently fixed to be the same. Default is a dark grey.
44
+ text_color : Color
45
+ The color to use for drawing tick and axis labels
46
+ minor_tick_length : float
47
+ The length of minor ticks, in pixels
48
+ major_tick_length : float
49
+ The length of major ticks, in pixels
50
+ tick_width : float
51
+ Line width for the ticks
52
+ tick_label_margin : float
53
+ Margin between ticks and tick labels
54
+ tick_font_size : float
55
+ The font size to use for rendering tick labels.
56
+ axis_width : float
57
+ Line width for the axis
58
+ axis_label : str
59
+ Text to use for the axis label
60
+ axis_label_margin : float
61
+ Margin between ticks and axis labels
62
+ axis_font_size : float
63
+ The font size to use for rendering axis labels.
64
+ font_size : float
65
+ Font size for both the tick and axis labels. If this is set,
66
+ tick_font_size and axis_font_size are ignored.
67
+ anchors : iterable
68
+ A 2-element iterable (tuple, list, etc.) giving the horizontal and
69
+ vertical alignment of the tick labels. The first element should be one
70
+ of 'left', 'center', or 'right', and the second element should be one
71
+ of 'bottom', 'middle', or 'top'. If this is not specified, it is
72
+ determined automatically.
73
+ """
74
+
75
+ def __init__(self, pos=None, domain=(0., 1.),
76
+ tick_direction=(-1., 0.),
77
+ scale_type="linear",
78
+ axis_color=(1, 1, 1),
79
+ tick_color=(0.7, 0.7, 0.7),
80
+ text_color='w',
81
+ minor_tick_length=5,
82
+ major_tick_length=10,
83
+ tick_width=2,
84
+ tick_label_margin=12,
85
+ tick_font_size=8,
86
+ axis_width=3,
87
+ axis_label=None,
88
+ axis_label_margin=35,
89
+ axis_font_size=10,
90
+ font_size=None,
91
+ anchors=None):
92
+
93
+ if scale_type != 'linear':
94
+ raise NotImplementedError('only linear scaling is currently '
95
+ 'supported')
96
+
97
+ if font_size is not None:
98
+ tick_font_size = font_size
99
+ axis_font_size = font_size
100
+
101
+ self._pos = None
102
+ self._domain = None
103
+
104
+ # If True, then axis stops at the first / last major tick.
105
+ # If False, then axis extends to edge of *pos*
106
+ # (private until we come up with a better name for this)
107
+ self._stop_at_major = (False, False)
108
+
109
+ self.ticker = Ticker(self, anchors=anchors)
110
+ self.tick_direction = np.array(tick_direction, float)
111
+ self.scale_type = scale_type
112
+
113
+ self._minor_tick_length = minor_tick_length # px
114
+ self._major_tick_length = major_tick_length # px
115
+ self._tick_label_margin = tick_label_margin # px
116
+ self._axis_label_margin = axis_label_margin # px
117
+
118
+ self._axis_label = axis_label
119
+
120
+ self._need_update = True
121
+
122
+ self._line = LineVisual(method='gl', width=axis_width, antialias=True,
123
+ color=axis_color)
124
+ self._ticks = LineVisual(method='gl', width=tick_width,
125
+ connect='segments', antialias=True,
126
+ color=tick_color)
127
+
128
+ self._text = TextVisual(font_size=tick_font_size, color=text_color)
129
+ self._axis_label_vis = TextVisual(font_size=axis_font_size,
130
+ color=text_color)
131
+ CompoundVisual.__init__(self, [self._line, self._text, self._ticks,
132
+ self._axis_label_vis])
133
+ if pos is not None:
134
+ self.pos = pos
135
+ self.domain = domain
136
+
137
+ @property
138
+ def text_color(self):
139
+ return self._text.color
140
+
141
+ @text_color.setter
142
+ def text_color(self, value):
143
+ self._text.color = value
144
+ self._axis_label_vis.color = value
145
+
146
+ @property
147
+ def axis_color(self):
148
+ return self._line.color
149
+
150
+ @axis_color.setter
151
+ def axis_color(self, value):
152
+ self._line.set_data(color=value)
153
+
154
+ @property
155
+ def axis_width(self):
156
+ return self._line.width
157
+
158
+ @axis_width.setter
159
+ def axis_width(self, value):
160
+ self._line.set_data(width=value)
161
+
162
+ @property
163
+ def tick_color(self):
164
+ return self._ticks.color
165
+
166
+ @tick_color.setter
167
+ def tick_color(self, value):
168
+ self._ticks.set_data(color=value)
169
+
170
+ @property
171
+ def tick_width(self):
172
+ return self._ticks.width
173
+
174
+ @tick_width.setter
175
+ def tick_width(self, value):
176
+ self._ticks.set_data(width=value)
177
+
178
+ @property
179
+ def tick_font_size(self):
180
+ return self._text.font_size
181
+
182
+ @tick_font_size.setter
183
+ def tick_font_size(self, value):
184
+ self._text.font_size = value
185
+
186
+ @updating_property
187
+ def tick_direction(self):
188
+ """The tick direction to use (in document coordinates)."""
189
+
190
+ @tick_direction.setter
191
+ def tick_direction(self, tick_direction):
192
+ self._tick_direction = np.array(tick_direction, float)
193
+
194
+ @property
195
+ def axis_font_size(self):
196
+ return self._axis_label_vis.font_size
197
+
198
+ @axis_font_size.setter
199
+ def axis_font_size(self, value):
200
+ self._axis_label_vis.font_size = value
201
+
202
+ @updating_property
203
+ def domain(self):
204
+ """The data values at the beginning and end of the axis, used for tick labels."""
205
+
206
+ @updating_property
207
+ def axis_label(self):
208
+ """Text to use for the axis label."""
209
+
210
+ @updating_property
211
+ def pos(self):
212
+ """Co-ordinates of start and end of the axis."""
213
+
214
+ @pos.setter
215
+ def pos(self, pos):
216
+ self._pos = np.array(pos, float)
217
+
218
+ @updating_property
219
+ def minor_tick_length(self):
220
+ """The length of minor ticks, in pixels"""
221
+
222
+ @updating_property
223
+ def major_tick_length(self):
224
+ """The length of major ticks, in pixels"""
225
+
226
+ @updating_property
227
+ def tick_label_margin(self):
228
+ """Margin between ticks and tick labels"""
229
+
230
+ @updating_property
231
+ def axis_label_margin(self):
232
+ """Margin between ticks and axis labels"""
233
+
234
+ @property
235
+ def _vec(self):
236
+ """Vector in the direction of the axis line"""
237
+ return self.pos[1] - self.pos[0]
238
+
239
+ def _update_subvisuals(self):
240
+ tick_pos, labels, tick_label_pos, anchors, axis_label_pos = \
241
+ self.ticker.get_update()
242
+
243
+ self._line.set_data(pos=self.pos, color=self.axis_color)
244
+ self._ticks.set_data(pos=tick_pos, color=self.tick_color)
245
+ self._text.text = list(labels)
246
+ self._text.pos = tick_label_pos
247
+ self._text.anchors = anchors
248
+ if self.axis_label is not None:
249
+ self._axis_label_vis.text = self.axis_label
250
+ self._axis_label_vis.pos = axis_label_pos
251
+ self._need_update = False
252
+
253
+ def _prepare_draw(self, view):
254
+ if self._pos is None:
255
+ return False
256
+ if self.axis_label is not None:
257
+ self._axis_label_vis.rotation = self._rotation_angle
258
+ if self._need_update:
259
+ self._update_subvisuals()
260
+
261
+ @property
262
+ def _rotation_angle(self):
263
+ """Determine the rotation angle of the axis as projected onto the canvas."""
264
+ # TODO: make sure we only call get_transform if the transform for
265
+ # the line is updated
266
+ tr = self._line.get_transform(map_from='visual', map_to='canvas')
267
+ trpos = tr.map(self.pos)
268
+ # Normalize homogeneous coordinates
269
+ # trpos /= trpos[:, 3:]
270
+ x1, y1, x2, y2 = trpos[:, :2].ravel()
271
+ if x1 > x2:
272
+ x1, y1, x2, y2 = x2, y2, x1, y1
273
+ return math.degrees(math.atan2(y2-y1, x2-x1))
274
+
275
+ def _compute_bounds(self, axis, view):
276
+ if axis == 2:
277
+ return (0., 0.)
278
+ # now axis in (0, 1)
279
+ return self.pos[:, axis].min(), self.pos[:, axis].max()
280
+
281
+
282
+ class Ticker(object):
283
+ """Class to determine tick marks
284
+
285
+ Parameters
286
+ ----------
287
+ axis : instance of AxisVisual
288
+ The AxisVisual to generate ticks for.
289
+ """
290
+
291
+ def __init__(self, axis, anchors=None):
292
+ self.axis = axis
293
+ self._anchors = anchors
294
+
295
+ def get_update(self):
296
+ major_tick_fractions, minor_tick_fractions, tick_labels = \
297
+ self._get_tick_frac_labels()
298
+ tick_pos, tick_label_pos, axis_label_pos, anchors = \
299
+ self._get_tick_positions(major_tick_fractions,
300
+ minor_tick_fractions)
301
+ return tick_pos, tick_labels, tick_label_pos, anchors, axis_label_pos
302
+
303
+ def _get_tick_positions(self, major_tick_fractions, minor_tick_fractions):
304
+ # tick direction is defined in visual coords, but use document
305
+ # coords to determine the tick length
306
+ trs = self.axis.transforms
307
+ visual_to_document = trs.get_transform('visual', 'document')
308
+ direction = np.array(self.axis.tick_direction)
309
+ direction /= np.linalg.norm(direction)
310
+
311
+ if self._anchors is None:
312
+ # use the document (pixel) coord system to set text anchors
313
+ anchors = []
314
+ if direction[0] < 0:
315
+ anchors.append('right')
316
+ elif direction[0] > 0:
317
+ anchors.append('left')
318
+ else:
319
+ anchors.append('center')
320
+ if direction[1] < 0:
321
+ anchors.append('bottom')
322
+ elif direction[1] > 0:
323
+ anchors.append('top')
324
+ else:
325
+ anchors.append('middle')
326
+ else:
327
+ anchors = self._anchors
328
+
329
+ # now figure out the tick positions in visual (data) coords
330
+ doc_unit = visual_to_document.map([[0, 0], direction[:2]])
331
+ doc_unit = doc_unit[1] - doc_unit[0]
332
+ doc_len = np.linalg.norm(doc_unit)
333
+
334
+ vectors = np.array([[0., 0.],
335
+ direction * self.axis.minor_tick_length / doc_len,
336
+ direction * self.axis.major_tick_length / doc_len,
337
+ direction * (self.axis.major_tick_length +
338
+ self.axis.tick_label_margin) / doc_len
339
+ ],
340
+ dtype=float)
341
+ minor_vector = vectors[1] - vectors[0]
342
+ major_vector = vectors[2] - vectors[0]
343
+ label_vector = vectors[3] - vectors[0]
344
+
345
+ axislabel_vector = direction * (self.axis.major_tick_length +
346
+ self.axis.axis_label_margin) / doc_len
347
+
348
+ major_origins, major_endpoints = self._tile_ticks(
349
+ major_tick_fractions, major_vector)
350
+
351
+ minor_origins, minor_endpoints = self._tile_ticks(
352
+ minor_tick_fractions, minor_vector)
353
+
354
+ tick_label_pos = major_origins + label_vector
355
+
356
+ axis_label_pos = 0.5 * (self.axis.pos[0] +
357
+ self.axis.pos[1]) + axislabel_vector
358
+
359
+ num_major = len(major_tick_fractions)
360
+ num_minor = len(minor_tick_fractions)
361
+
362
+ c = np.empty([(num_major + num_minor) * 2, 2])
363
+
364
+ c[0:(num_major-1)*2+1:2] = major_origins
365
+ c[1:(num_major-1)*2+2:2] = major_endpoints
366
+ c[(num_major-1)*2+2::2] = minor_origins
367
+ c[(num_major-1)*2+3::2] = minor_endpoints
368
+
369
+ return c, tick_label_pos, axis_label_pos, anchors
370
+
371
+ def _tile_ticks(self, frac, tickvec):
372
+ """Tiles tick marks along the axis."""
373
+ origins = np.tile(self.axis._vec, (len(frac), 1))
374
+ origins = self.axis.pos[0].T + (origins.T*frac).T
375
+ endpoints = tickvec + origins
376
+ return origins, endpoints
377
+
378
+ def _get_tick_frac_labels(self):
379
+ """Get the major ticks, minor ticks, and major labels"""
380
+ minor_num = 4 # number of minor ticks per major division
381
+ if (self.axis.scale_type == 'linear'):
382
+ domain = self.axis.domain
383
+ if domain[1] < domain[0]:
384
+ flip = True
385
+ domain = domain[::-1]
386
+ else:
387
+ flip = False
388
+ offset = domain[0]
389
+ scale = domain[1] - domain[0]
390
+
391
+ transforms = self.axis.transforms
392
+ length = self.axis.pos[1] - self.axis.pos[0] # in logical coords
393
+ n_inches = np.sqrt(np.sum(length ** 2)) / transforms.dpi
394
+
395
+ major = _get_ticks_talbot(domain[0], domain[1], n_inches, 2)
396
+
397
+ labels = ['%g' % x for x in major]
398
+ majstep = major[1] - major[0]
399
+ minor = []
400
+ minstep = majstep / (minor_num + 1)
401
+ minstart = 0 if self.axis._stop_at_major[0] else -1
402
+ minstop = -1 if self.axis._stop_at_major[1] else 0
403
+ for i in range(minstart, len(major) + minstop):
404
+ maj = major[0] + i * majstep
405
+ minor.extend(np.linspace(maj + minstep,
406
+ maj + majstep - minstep,
407
+ minor_num))
408
+ major_frac = major - offset
409
+ minor_frac = np.array(minor) - offset
410
+ if scale != 0: # maybe something better to do here?
411
+ major_frac /= scale
412
+ minor_frac /= scale
413
+ use_mask = (major_frac > -0.0001) & (major_frac < 1.0001)
414
+ major_frac = major_frac[use_mask]
415
+ labels = [l for li, l in enumerate(labels) if use_mask[li]]
416
+ minor_frac = minor_frac[(minor_frac > -0.0001) &
417
+ (minor_frac < 1.0001)]
418
+ # Flip ticks coordinates if necessary :
419
+ if flip:
420
+ major_frac = 1 - major_frac
421
+ minor_frac = 1 - minor_frac
422
+ elif self.axis.scale_type == 'logarithmic':
423
+ return NotImplementedError
424
+ elif self.axis.scale_type == 'power':
425
+ return NotImplementedError
426
+ return major_frac, minor_frac, labels
427
+
428
+
429
+ # #############################################################################
430
+ # Translated from matplotlib
431
+
432
+ class MaxNLocator(object):
433
+ """Select no more than N intervals at nice locations."""
434
+
435
+ def __init__(self, nbins=10, steps=None, trim=True, integer=False,
436
+ symmetric=False, prune=None):
437
+ """
438
+ Keyword args:
439
+ *nbins*
440
+ Maximum number of intervals; one less than max number of ticks.
441
+ *steps*
442
+ Sequence of nice numbers starting with 1 and ending with 10;
443
+ e.g., [1, 2, 4, 5, 10]
444
+ *integer*
445
+ If True, ticks will take only integer values.
446
+ *symmetric*
447
+ If True, autoscaling will result in a range symmetric
448
+ about zero.
449
+ *prune*
450
+ ['lower' | 'upper' | 'both' | None]
451
+ Remove edge ticks -- useful for stacked or ganged plots
452
+ where the upper tick of one axes overlaps with the lower
453
+ tick of the axes above it.
454
+ If prune=='lower', the smallest tick will
455
+ be removed. If prune=='upper', the largest tick will be
456
+ removed. If prune=='both', the largest and smallest ticks
457
+ will be removed. If prune==None, no ticks will be removed.
458
+ """
459
+ self._nbins = int(nbins)
460
+ self._trim = trim
461
+ self._integer = integer
462
+ self._symmetric = symmetric
463
+ if prune is not None and prune not in ['upper', 'lower', 'both']:
464
+ raise ValueError(
465
+ "prune must be 'upper', 'lower', 'both', or None")
466
+ self._prune = prune
467
+ if steps is None:
468
+ steps = [1, 2, 2.5, 3, 4, 5, 6, 8, 10]
469
+ else:
470
+ if int(steps[-1]) != 10:
471
+ steps = list(steps)
472
+ steps.append(10)
473
+ self._steps = steps
474
+ self._integer = integer
475
+ if self._integer:
476
+ self._steps = [n for n in self._steps
477
+ if divmod(n, 1)[1] < 0.001]
478
+
479
+ def bin_boundaries(self, vmin, vmax):
480
+ nbins = self._nbins
481
+ scale, offset = scale_range(vmin, vmax, nbins)
482
+ if self._integer:
483
+ scale = max(1, scale)
484
+ vmin = vmin - offset
485
+ vmax = vmax - offset
486
+ raw_step = (vmax - vmin) / nbins
487
+ scaled_raw_step = raw_step / scale
488
+ best_vmax = vmax
489
+ best_vmin = vmin
490
+
491
+ for step in self._steps:
492
+ if step < scaled_raw_step:
493
+ continue
494
+ step *= scale
495
+ best_vmin = step * divmod(vmin, step)[0]
496
+ best_vmax = best_vmin + step * nbins
497
+ if (best_vmax >= vmax):
498
+ break
499
+ if self._trim:
500
+ extra_bins = int(divmod((best_vmax - vmax), step)[0])
501
+ nbins -= extra_bins
502
+ return (np.arange(nbins + 1) * step + best_vmin + offset)
503
+
504
+ def __call__(self):
505
+ vmin, vmax = self.axis.get_view_interval()
506
+ return self.tick_values(vmin, vmax)
507
+
508
+ def tick_values(self, vmin, vmax):
509
+ locs = self.bin_boundaries(vmin, vmax)
510
+ prune = self._prune
511
+ if prune == 'lower':
512
+ locs = locs[1:]
513
+ elif prune == 'upper':
514
+ locs = locs[:-1]
515
+ elif prune == 'both':
516
+ locs = locs[1:-1]
517
+ return locs
518
+
519
+ def view_limits(self, dmin, dmax):
520
+ if self._symmetric:
521
+ maxabs = max(abs(dmin), abs(dmax))
522
+ dmin = -maxabs
523
+ dmax = maxabs
524
+ return np.take(self.bin_boundaries(dmin, dmax), [0, -1])
525
+
526
+
527
+ def scale_range(vmin, vmax, n=1, threshold=100):
528
+ dv = abs(vmax - vmin)
529
+ if dv == 0: # maxabsv == 0 is a special case of this.
530
+ return 1.0, 0.0
531
+ # Note: this should never occur because
532
+ # vmin, vmax should have been checked by nonsingular(),
533
+ # and spread apart if necessary.
534
+ meanv = 0.5 * (vmax + vmin)
535
+ if abs(meanv) / dv < threshold:
536
+ offset = 0
537
+ elif meanv > 0:
538
+ ex = divmod(np.log10(meanv), 1)[0]
539
+ offset = 10 ** ex
540
+ else:
541
+ ex = divmod(np.log10(-meanv), 1)[0]
542
+ offset = -10 ** ex
543
+ ex = divmod(np.log10(dv / n), 1)[0]
544
+ scale = 10 ** ex
545
+ return scale, offset
546
+
547
+
548
+ # #############################################################################
549
+ # Tranlated from http://www.justintalbot.com/research/axis-labeling/
550
+
551
+ # See "An Extension of Wilkinson's Algorithm for Positioning Tick Labels
552
+ # on Axes" # by Justin Talbot, Sharon Lin, and Pat Hanrahan, InfoVis 2010.
553
+
554
+
555
+ def _coverage(dmin, dmax, lmin, lmax):
556
+ return 1 - 0.5 * ((dmax - lmax) ** 2 +
557
+ (dmin - lmin) ** 2) / (0.1 * (dmax - dmin)) ** 2
558
+
559
+
560
+ def _coverage_max(dmin, dmax, span):
561
+ range_ = dmax - dmin
562
+ if span <= range_:
563
+ return 1.
564
+ else:
565
+ half = (span - range_) / 2.0
566
+ return 1 - half ** 2 / (0.1 * range_) ** 2
567
+
568
+
569
+ def _density(k, m, dmin, dmax, lmin, lmax):
570
+ r = (k-1.0) / (lmax-lmin)
571
+ rt = (m-1.0) / (max(lmax, dmax) - min(lmin, dmin))
572
+ return 2 - max(r / rt, rt / r)
573
+
574
+
575
+ def _density_max(k, m):
576
+ return 2 - (k-1.0) / (m-1.0) if k >= m else 1.
577
+
578
+
579
+ def _simplicity(q, Q, j, lmin, lmax, lstep):
580
+ eps = 1e-10
581
+ n = len(Q)
582
+ i = Q.index(q) + 1
583
+ if ((lmin % lstep) < eps or
584
+ (lstep - lmin % lstep) < eps) and lmin <= 0 and lmax >= 0:
585
+ v = 1
586
+ else:
587
+ v = 0
588
+ return (n - i) / (n - 1.0) + v - j
589
+
590
+
591
+ def _simplicity_max(q, Q, j):
592
+ n = len(Q)
593
+ i = Q.index(q) + 1
594
+ return (n - i)/(n - 1.0) + 1. - j
595
+
596
+
597
+ def _get_ticks_talbot(dmin, dmax, n_inches, density=1.):
598
+ # density * size gives target number of intervals,
599
+ # density * size + 1 gives target number of tick marks,
600
+ # the density function converts this back to a density in data units
601
+ # (not inches)
602
+ n_inches = max(n_inches, 2.0) # Set minimum otherwise code can crash :(
603
+
604
+ if dmin == dmax:
605
+ return np.array([dmin, dmax])
606
+
607
+ m = density * n_inches + 1.0
608
+ only_inside = False # we cull values outside ourselves
609
+ Q = [1, 5, 2, 2.5, 4, 3]
610
+ w = [0.25, 0.2, 0.5, 0.05]
611
+ best_score = -2.0
612
+ best = None
613
+
614
+ j = 1.0
615
+ n_max = 1000
616
+ while j < n_max:
617
+ for q in Q:
618
+ sm = _simplicity_max(q, Q, j)
619
+
620
+ if w[0] * sm + w[1] + w[2] + w[3] < best_score:
621
+ j = n_max
622
+ break
623
+
624
+ k = 2.0
625
+ while k < n_max:
626
+ dm = _density_max(k, n_inches)
627
+
628
+ if w[0] * sm + w[1] + w[2] * dm + w[3] < best_score:
629
+ break
630
+
631
+ delta = (dmax-dmin)/(k+1.0)/j/q
632
+ z = np.ceil(np.log10(delta))
633
+
634
+ while z < float('infinity'):
635
+ step = j * q * 10 ** z
636
+ cm = _coverage_max(dmin, dmax, step*(k-1.0))
637
+
638
+ if (w[0] * sm +
639
+ w[1] * cm +
640
+ w[2] * dm +
641
+ w[3] < best_score):
642
+ break
643
+
644
+ min_start = np.floor(dmax/step)*j - (k-1.0)*j
645
+ max_start = np.ceil(dmin/step)*j
646
+
647
+ if min_start > max_start:
648
+ z = z+1
649
+ break
650
+
651
+ for start in range(int(min_start), int(max_start)+1):
652
+ lmin = start * (step/j)
653
+ lmax = lmin + step*(k-1.0)
654
+ lstep = step
655
+
656
+ s = _simplicity(q, Q, j, lmin, lmax, lstep)
657
+ c = _coverage(dmin, dmax, lmin, lmax)
658
+ d = _density(k, m, dmin, dmax, lmin, lmax)
659
+ leg = 1. # _legibility(lmin, lmax, lstep)
660
+
661
+ score = w[0] * s + w[1] * c + w[2] * d + w[3] * leg
662
+
663
+ if (score > best_score and
664
+ (not only_inside or (lmin >= dmin and
665
+ lmax <= dmax))):
666
+ best_score = score
667
+ best = (lmin, lmax, lstep, q, k)
668
+ z += 1
669
+ k += 1
670
+ if k == n_max:
671
+ raise RuntimeError('could not converge on ticks')
672
+ j += 1
673
+ if j == n_max:
674
+ raise RuntimeError('could not converge on ticks')
675
+
676
+ if best is None:
677
+ raise RuntimeError('could not converge on ticks')
678
+ return np.arange(best[4]) * best[2] + best[0]