vispy 0.14.0__cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.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 (519) 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 +968 -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 +1134 -0
  45. vispy/color/tests/__init__.py +0 -0
  46. vispy/color/tests/test_color.py +352 -0
  47. vispy/conftest.py +12 -0
  48. vispy/ext/__init__.py +0 -0
  49. vispy/ext/cocoapy.py +1542 -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 +134 -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 +698 -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 +506 -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 +566 -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 +1816 -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 +1045 -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 +106 -0
  274. vispy/scene/cameras/base_camera.py +538 -0
  275. vispy/scene/cameras/fly.py +474 -0
  276. vispy/scene/cameras/magnify.py +163 -0
  277. vispy/scene/cameras/panzoom.py +308 -0
  278. vispy/scene/cameras/perspective.py +333 -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 +173 -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 +446 -0
  306. vispy/testing/_testing.py +416 -0
  307. vispy/testing/image_tester.py +473 -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 +17 -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 +4 -0
  377. vispy/visuals/__init__.py +50 -0
  378. vispy/visuals/_scalable_textures.py +485 -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 +163 -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 +796 -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 +105 -0
  430. vispy/visuals/gridmesh.py +98 -0
  431. vispy/visuals/histogram.py +58 -0
  432. vispy/visuals/image.py +688 -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 +810 -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_histogram.py +24 -0
  477. vispy/visuals/tests/test_image.py +390 -0
  478. vispy/visuals/tests/test_image_complex.py +36 -0
  479. vispy/visuals/tests/test_infinite_line.py +53 -0
  480. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  481. vispy/visuals/tests/test_isosurface.py +22 -0
  482. vispy/visuals/tests/test_linear_region.py +152 -0
  483. vispy/visuals/tests/test_markers.py +54 -0
  484. vispy/visuals/tests/test_mesh.py +261 -0
  485. vispy/visuals/tests/test_mesh_normals.py +218 -0
  486. vispy/visuals/tests/test_polygon.py +112 -0
  487. vispy/visuals/tests/test_rectangle.py +163 -0
  488. vispy/visuals/tests/test_regular_polygon.py +111 -0
  489. vispy/visuals/tests/test_scalable_textures.py +180 -0
  490. vispy/visuals/tests/test_sdf.py +73 -0
  491. vispy/visuals/tests/test_spectrogram.py +42 -0
  492. vispy/visuals/tests/test_text.py +95 -0
  493. vispy/visuals/tests/test_volume.py +542 -0
  494. vispy/visuals/tests/test_windbarb.py +33 -0
  495. vispy/visuals/text/__init__.py +7 -0
  496. vispy/visuals/text/_sdf_cpu.cpython-312-aarch64-linux-gnu.so +0 -0
  497. vispy/visuals/text/_sdf_cpu.pyx +110 -0
  498. vispy/visuals/text/_sdf_gpu.py +316 -0
  499. vispy/visuals/text/text.py +675 -0
  500. vispy/visuals/transforms/__init__.py +34 -0
  501. vispy/visuals/transforms/_util.py +191 -0
  502. vispy/visuals/transforms/base_transform.py +233 -0
  503. vispy/visuals/transforms/chain.py +300 -0
  504. vispy/visuals/transforms/interactive.py +98 -0
  505. vispy/visuals/transforms/linear.py +564 -0
  506. vispy/visuals/transforms/nonlinear.py +398 -0
  507. vispy/visuals/transforms/tests/__init__.py +0 -0
  508. vispy/visuals/transforms/tests/test_transforms.py +243 -0
  509. vispy/visuals/transforms/transform_system.py +339 -0
  510. vispy/visuals/tube.py +173 -0
  511. vispy/visuals/visual.py +923 -0
  512. vispy/visuals/volume.py +1335 -0
  513. vispy/visuals/windbarb.py +291 -0
  514. vispy/visuals/xyz_axis.py +34 -0
  515. vispy-0.14.0.dist-info/LICENSE.txt +36 -0
  516. vispy-0.14.0.dist-info/METADATA +218 -0
  517. vispy-0.14.0.dist-info/RECORD +519 -0
  518. vispy-0.14.0.dist-info/WHEEL +6 -0
  519. vispy-0.14.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,97 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ """
4
+ Tests for texture-based colormap
5
+ All images are of size (100,100) to keep a small file size
6
+ """
7
+
8
+ import numpy as np
9
+
10
+ from vispy.scene.visuals import Image
11
+ from vispy.testing import (requires_application, TestingCanvas,
12
+ run_tests_if_main)
13
+ from vispy.testing.image_tester import assert_image_approved
14
+ from vispy.color import Colormap
15
+
16
+ size = (100, 100)
17
+
18
+
19
+ @requires_application()
20
+ def test_colormap():
21
+ """Test colormap support for non-uniformly distributed control-points"""
22
+ with TestingCanvas(size=size, bgcolor='w') as c:
23
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
24
+ data = idata.reshape((size[0], size[1]))
25
+ image = Image(cmap=Colormap(colors=['k', 'w', 'r'],
26
+ controls=[0.0, 0.1, 1.0]),
27
+ clim='auto', parent=c.scene)
28
+ image.set_data(data)
29
+ assert_image_approved(c.render(), "visuals/colormap_kwr.png")
30
+
31
+
32
+ @requires_application()
33
+ def test_colormap_discrete():
34
+ """Test discrete RGB colormap"""
35
+ with TestingCanvas(size=size, bgcolor='w') as c:
36
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
37
+ data = idata.reshape((size[0], size[1]))
38
+ image = Image(cmap=Colormap(colors=['r', 'g', 'b'],
39
+ interpolation='zero'),
40
+ clim='auto', parent=c.scene)
41
+ image.set_data(data)
42
+ assert_image_approved(c.render(), "visuals/colormap_rgb.png")
43
+
44
+
45
+ @requires_application()
46
+ def test_colormap_discrete_nu():
47
+ """Test discrete colormap with non-uniformly distributed control-points"""
48
+ with TestingCanvas(size=size, bgcolor='w') as c:
49
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
50
+ data = idata.reshape((size[0], size[1]))
51
+ image = Image(cmap=Colormap(np.array([[0, .75, 0], [.75, .25, .5]]),
52
+ [0., .25, 1.], interpolation='zero'),
53
+ clim='auto', parent=c.scene)
54
+ image.set_data(data)
55
+ assert_image_approved(c.render(), "visuals/colormap_nu.png")
56
+
57
+
58
+ @requires_application()
59
+ def test_colormap_single_hue():
60
+ """Test colormap support using a single hue()"""
61
+ from vispy.color.colormap import SingleHue
62
+ with TestingCanvas(size=size, bgcolor='w') as c:
63
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
64
+ data = idata.reshape((size[0], size[1]))
65
+ cmap = SingleHue(255)
66
+ image = Image(cmap=cmap,
67
+ clim='auto', parent=c.scene)
68
+ image.set_data(data)
69
+ assert_image_approved(c.render(), "visuals/colormap_hue.png")
70
+
71
+
72
+ @requires_application()
73
+ def test_colormap_coolwarm():
74
+ """Test colormap support using coolwarm preset colormap"""
75
+ with TestingCanvas(size=size, bgcolor='w') as c:
76
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
77
+ data = idata.reshape((size[0], size[1]))
78
+ image = Image(cmap='coolwarm', clim='auto', parent=c.scene)
79
+ image.set_data(data)
80
+ assert_image_approved(c.render(), "visuals/colormap_coolwarm.png")
81
+
82
+
83
+ @requires_application()
84
+ def test_colormap_CubeHelix():
85
+ """Test colormap support using cubehelix colormap in only blues"""
86
+ from vispy.color.colormap import CubeHelixColormap
87
+ with TestingCanvas(size=size, bgcolor='w') as c:
88
+ idata = np.linspace(255, 0, size[0]*size[1]).astype(np.ubyte)
89
+ data = idata.reshape((size[0], size[1]))
90
+ cmap = CubeHelixColormap(rot=0, start=0)
91
+ image = Image(cmap=cmap,
92
+ clim='auto', parent=c.scene)
93
+ image.set_data(data)
94
+ assert_image_approved(c.render(), "visuals/colormap_cubehelix.png")
95
+
96
+
97
+ run_tests_if_main()
@@ -0,0 +1,122 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
3
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
+
5
+ """
6
+ Tests for EllipseVisual
7
+ All images are of size (100,100) to keep a small file size
8
+ """
9
+
10
+ from vispy.scene import visuals, transforms
11
+ from vispy.testing import (requires_application, TestingCanvas,
12
+ run_tests_if_main)
13
+ from vispy.testing.image_tester import assert_image_approved
14
+
15
+
16
+ @requires_application()
17
+ def test_circle_draw():
18
+ """Test drawing circles without transform using EllipseVisual"""
19
+ with TestingCanvas() as c:
20
+ ellipse = visuals.Ellipse(center=(75, 35, 0), radius=20,
21
+ color=(1, 0, 0, 1),
22
+ parent=c.scene)
23
+ assert_image_approved(c.render(), 'visuals/circle1.png')
24
+
25
+ ellipse.parent = None
26
+ ellipse = visuals.Ellipse(center=(75, 35, 0), radius=20,
27
+ color=(1, 0, 0, 1),
28
+ border_color=(0, 1, 1, 1),
29
+ parent=c.scene)
30
+ assert_image_approved(c.render(), 'visuals/circle2.png')
31
+
32
+ ellipse.parent = None
33
+ ellipse = visuals.Ellipse(center=(75, 35, 0), radius=20,
34
+ border_color=(0, 1, 1, 1),
35
+ parent=c.scene)
36
+
37
+ # low corr here because borders have some variability
38
+ # esp. w/HiDPI
39
+ assert_image_approved(c.render(), 'visuals/circle3.png',
40
+ min_corr=0.7)
41
+
42
+
43
+ @requires_application()
44
+ def test_ellipse_draw():
45
+ """Test drawing transformed ellipses using EllipseVisual"""
46
+ with TestingCanvas() as c:
47
+ ellipse = visuals.Ellipse(center=(0., 0.), radius=(20, 15),
48
+ color=(0, 0, 1, 1),
49
+ parent=c.scene)
50
+ ellipse.transform = transforms.STTransform(scale=(2.0, 3.0),
51
+ translate=(50, 50))
52
+ assert_image_approved(c.render(), 'visuals/ellipse1.png')
53
+
54
+ ellipse.parent = None
55
+ ellipse = visuals.Ellipse(center=(0., 0.), radius=(20, 15),
56
+ color=(0, 0, 1, 1),
57
+ border_color=(1, 0, 0, 1),
58
+ parent=c.scene)
59
+ ellipse.transform = transforms.STTransform(scale=(2.0, 3.0),
60
+ translate=(50, 50))
61
+ assert_image_approved(c.render(), 'visuals/ellipse2.png')
62
+
63
+ ellipse.parent = None
64
+ ellipse = visuals.Ellipse(center=(0., 0.), radius=(20, 15),
65
+ border_color=(1, 0, 0, 1),
66
+ parent=c.scene)
67
+ ellipse.transform = transforms.STTransform(scale=(2.0, 3.0),
68
+ translate=(50, 50))
69
+ assert_image_approved(c.render(), 'visuals/ellipse3.png',
70
+ min_corr=0.7)
71
+
72
+
73
+ @requires_application()
74
+ def test_arc_draw1():
75
+ """Test drawing arcs using EllipseVisual"""
76
+ with TestingCanvas() as c:
77
+ ellipse = visuals.Ellipse(center=(50., 50.), radius=(20, 15),
78
+ start_angle=150., span_angle=120.,
79
+ color=(0, 0, 1, 1),
80
+ parent=c.scene)
81
+ assert_image_approved(c.render(), 'visuals/arc1.png')
82
+
83
+ ellipse.parent = None
84
+ ellipse = visuals.Ellipse(center=(50., 50.), radius=(20, 15),
85
+ start_angle=150., span_angle=120.,
86
+ border_color=(1, 0, 0, 1),
87
+ parent=c.scene)
88
+ assert_image_approved(c.render(), 'visuals/arc2.png',
89
+ min_corr=0.6)
90
+
91
+
92
+ @requires_application()
93
+ def test_reactive_draw():
94
+ """Test reactive ellipse attributes"""
95
+ with TestingCanvas() as c:
96
+ ellipse = visuals.Ellipse(center=[75, 35, 0.], radius=[20, 15],
97
+ color='yellow',
98
+ parent=c.scene)
99
+
100
+ ellipse.center = [70, 40, 0.]
101
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse1.png')
102
+
103
+ ellipse.radius = 25
104
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse2.png')
105
+
106
+ ellipse.color = 'red'
107
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse3.png')
108
+
109
+ ellipse.border_color = 'yellow'
110
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse4.png')
111
+
112
+ ellipse.start_angle = 140.
113
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse5.png')
114
+
115
+ ellipse.span_angle = 100.
116
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse6.png')
117
+
118
+ ellipse.num_segments = 10.
119
+ assert_image_approved(c.render(), 'visuals/reactive_ellipse7.png')
120
+
121
+
122
+ run_tests_if_main()
@@ -0,0 +1,24 @@
1
+ # -*- coding: utf-8 -*-
2
+ import numpy as np
3
+
4
+ from vispy.visuals.transforms import STTransform
5
+ from vispy.scene.visuals import Histogram
6
+ from vispy.testing import (requires_application, TestingCanvas,
7
+ run_tests_if_main)
8
+ from vispy.testing.image_tester import assert_image_approved
9
+
10
+
11
+ @requires_application()
12
+ def test_histogram():
13
+ """Test histogram visual"""
14
+ size = (200, 100)
15
+ with TestingCanvas(size=size, bgcolor='w') as c:
16
+ np.random.seed(2397)
17
+ data = np.random.normal(size=100)
18
+ hist = Histogram(data, bins=20, color='k', parent=c.scene)
19
+ hist.transform = STTransform((size[0] // 10, -size[1] // 20, 1),
20
+ (100, size[1]))
21
+ assert_image_approved(c.render(), "visuals/histogram.png")
22
+
23
+
24
+ run_tests_if_main()
@@ -0,0 +1,390 @@
1
+ # -*- coding: utf-8 -*-
2
+ from unittest import mock
3
+
4
+ from vispy.scene import Image, PanZoomCamera
5
+ from vispy.testing import (requires_application, TestingCanvas,
6
+ run_tests_if_main, IS_CI)
7
+ from vispy.testing.image_tester import assert_image_approved, downsample
8
+
9
+ import numpy as np
10
+ import pytest
11
+
12
+ from vispy.testing.rendered_array_tester import compare_render, max_for_dtype
13
+
14
+
15
+ @requires_application()
16
+ @pytest.mark.parametrize('is_3d', [True, False])
17
+ def test_image(is_3d):
18
+ """Test image visual"""
19
+ size = (100, 50)
20
+ with TestingCanvas(size=size, bgcolor='w') as c:
21
+ image = Image(cmap='grays', clim=[0, 1], parent=c.scene)
22
+ shape = (size[1]-10, size[0]-10) + ((3,) if is_3d else ())
23
+ np.random.seed(379823)
24
+ data = np.random.rand(*shape)
25
+ image.set_data(data)
26
+ assert_image_approved(c.render(), "visuals/image%s.png" %
27
+ ("_rgb" if is_3d else "_mono"))
28
+
29
+ # change to auto clims after first draw
30
+ image.clim = "auto"
31
+ assert_image_approved(c.render(), "visuals/image%s.png" %
32
+ ("_rgb" if is_3d else "_mono"))
33
+
34
+
35
+ @requires_application()
36
+ @pytest.mark.parametrize('gamma', [None, -0.5, "0.5"])
37
+ def test_bad_init_gamma(gamma):
38
+ """Test creating an Image with a bad gamma value."""
39
+ with TestingCanvas(size=(100, 50)) as c:
40
+ pytest.raises((TypeError, ValueError), Image, gamma=gamma, parent=c.scene)
41
+
42
+
43
+ def _make_test_data(shape, input_dtype):
44
+ data = np.random.random_sample(shape)
45
+ if data.ndim == 3 and data.shape[-1] == 4:
46
+ # RGBA - make alpha fully opaque
47
+ data[..., -1] = 1.0
48
+ max_val = max_for_dtype(input_dtype)
49
+ if max_val != 1:
50
+ data *= max_val
51
+ data = data.astype(input_dtype)
52
+ return data
53
+
54
+
55
+ def _set_image_data(image, data, should_fail):
56
+ if should_fail:
57
+ pytest.raises(ValueError, image.set_data, data)
58
+ return
59
+ image.set_data(data)
60
+
61
+
62
+ def _get_orig_and_new_clims(input_dtype):
63
+ new_clim = (0.3, 0.8)
64
+ max_val = max_for_dtype(input_dtype)
65
+ if np.issubdtype(input_dtype, np.integer):
66
+ new_clim = (int(new_clim[0] * max_val), int(new_clim[1] * max_val))
67
+ return (0, max_val), new_clim
68
+
69
+
70
+ @requires_application()
71
+ @pytest.mark.parametrize('data_on_init', [False, True])
72
+ @pytest.mark.parametrize('clim_on_init', [False, True])
73
+ @pytest.mark.parametrize('num_channels', [0, 1, 3, 4])
74
+ @pytest.mark.parametrize('texture_format', [None, '__dtype__', 'auto'])
75
+ @pytest.mark.parametrize('input_dtype', [np.uint8, np.uint16, np.float32, np.float64])
76
+ def test_image_clims_and_gamma(input_dtype, texture_format, num_channels,
77
+ clim_on_init, data_on_init):
78
+ """Test image visual with clims and gamma on shader."""
79
+ size = (80, 80)
80
+ if texture_format == '__dtype__':
81
+ texture_format = input_dtype
82
+ shape = size + (num_channels,) if num_channels > 0 else size
83
+ np.random.seed(0)
84
+ data = _make_test_data(shape, input_dtype)
85
+ orig_clim, new_clim = _get_orig_and_new_clims(input_dtype)
86
+ # 16-bit integers and above seem to have precision loss when scaled on the CPU
87
+ is_16int_cpu_scaled = (np.dtype(input_dtype).itemsize >= 2 and
88
+ np.issubdtype(input_dtype, np.integer) and
89
+ texture_format is None)
90
+ clim_atol = 2 if is_16int_cpu_scaled else 1
91
+ gamma_atol = 3 if is_16int_cpu_scaled else 2
92
+
93
+ kwargs = {}
94
+ if clim_on_init:
95
+ kwargs['clim'] = orig_clim
96
+ if data_on_init:
97
+ kwargs['data'] = data
98
+ # default is RGBA, anything except auto requires reformat
99
+ set_data_fails = (num_channels != 4 and
100
+ texture_format is not None and
101
+ texture_format != 'auto')
102
+
103
+ with TestingCanvas(size=size[::-1], bgcolor="w") as c:
104
+ image = Image(cmap='grays', texture_format=texture_format,
105
+ parent=c.scene, **kwargs)
106
+ if not data_on_init:
107
+ _set_image_data(image, data, set_data_fails)
108
+ if set_data_fails:
109
+ return
110
+ rendered = c.render()
111
+ _dtype = rendered.dtype
112
+ shape_ratio = rendered.shape[0] // data.shape[0]
113
+ rendered1 = downsample(rendered, shape_ratio, axis=(0, 1)).astype(_dtype)
114
+ compare_render(data, rendered1)
115
+
116
+ # adjust color limits
117
+ image.clim = new_clim
118
+ rendered2 = downsample(c.render(), shape_ratio, axis=(0, 1)).astype(_dtype)
119
+ scaled_data = (np.clip(data, new_clim[0], new_clim[1]) - new_clim[0]) / (new_clim[1] - new_clim[0])
120
+ compare_render(scaled_data, rendered2, rendered1, atol=clim_atol)
121
+
122
+ # adjust gamma
123
+ image.gamma = 2
124
+ rendered3 = downsample(c.render(), shape_ratio, axis=(0, 1)).astype(_dtype)
125
+ compare_render(scaled_data ** 2, rendered3, rendered2, atol=gamma_atol)
126
+
127
+
128
+ @pytest.mark.xfail(IS_CI, reason="CI environments sometimes treat NaN as 0")
129
+ @requires_application()
130
+ @pytest.mark.parametrize('texture_format', [None, 'auto'])
131
+ def test_image_nan_single_band(texture_format):
132
+ size = (40, 40)
133
+ data = np.ones((40, 40))
134
+ data[:5, :5] = np.nan
135
+ data[:5, -5:] = 0
136
+
137
+ expected = (np.ones((40, 40, 4)) * 255).astype(np.uint8)
138
+ # black square
139
+ expected[:5, -5:, :3] = 0
140
+ if texture_format is None:
141
+ # CPU scaling's NaNs get converted to 0s
142
+ expected[:5, :5, :3] = 0
143
+ else:
144
+ # GPU receives NaNs
145
+ # nan - transparent square
146
+ expected[:5, :5, 0] = 0
147
+ expected[:5, :5, 1] = 255 # match the 'green' background
148
+ expected[:5, :5, 2] = 0
149
+
150
+ with TestingCanvas(size=size[::-1], bgcolor=(0, 1, 0)) as c:
151
+ Image(data, cmap='grays',
152
+ texture_format=texture_format, parent=c.scene)
153
+ rendered = c.render()
154
+ np.testing.assert_allclose(rendered, expected)
155
+
156
+
157
+ @requires_application()
158
+ @pytest.mark.parametrize('num_bands', [3, 4])
159
+ @pytest.mark.parametrize('texture_format', [None, 'auto'])
160
+ def test_image_nan_rgb(texture_format, num_bands):
161
+ size = (40, 40)
162
+ data = np.ones((40, 40, num_bands))
163
+ data[:5, :5, :3] = np.nan # upper left - RGB all NaN
164
+ data[:5, 20:25, 0] = np.nan # upper middle - R NaN
165
+ data[:5, -5:, :3] = 0 # upper right - opaque RGB black square
166
+ data[-5:, -5:, :] = np.nan # lower right RGBA all NaN
167
+ if num_bands == 4:
168
+ data[-5:, :5, 3] = np.nan # lower left - Alpha NaN
169
+
170
+ expected = (np.ones((40, 40, 4)) * 255).astype(np.uint8)
171
+ # upper left - NaN goes to opaque black
172
+ expected[:5, :5, :3] = 0
173
+ # upper middle -> NaN R goes to 0
174
+ expected[:5, 20:25, 0] = 0
175
+ # upper right - opaque RGB black square
176
+ expected[:5, -5:, :3] = 0
177
+ # lower right - NaN RGB/A goes to 0
178
+ # RGBA case - we see the green background behind the image
179
+ expected[-5:, -5:, 0] = 0
180
+ expected[-5:, -5:, 2] = 0
181
+ if num_bands == 3:
182
+ # RGB case - opaque black because Alpha defaults 1
183
+ expected[-5:, -5:, 1] = 0
184
+ # lower left - NaN Alpha goes to 0
185
+ if num_bands == 4:
186
+ # see the green background behind the image
187
+ expected[-5:, :5, 0] = 0
188
+ expected[-5:, :5, 2] = 0
189
+
190
+ with TestingCanvas(size=size[::-1], bgcolor=(0, 1, 0)) as c:
191
+ Image(data, cmap='grays',
192
+ texture_format=texture_format, parent=c.scene)
193
+ rendered = c.render()
194
+ np.testing.assert_allclose(rendered, expected)
195
+
196
+
197
+ @requires_application()
198
+ @pytest.mark.parametrize('num_channels', [0, 1, 3, 4])
199
+ @pytest.mark.parametrize('texture_format', [None, 'auto'])
200
+ def test_image_equal_clims(texture_format, num_channels):
201
+ """Test image visual with equal clims."""
202
+ size = (40, 40)
203
+ input_dtype = np.uint8
204
+ shape = size + (num_channels,) if num_channels > 0 else size
205
+ np.random.seed(0)
206
+ data = _make_test_data(shape, input_dtype)
207
+ with TestingCanvas(size=size[::-1], bgcolor="w") as c:
208
+ Image(data, cmap='viridis',
209
+ texture_format=texture_format,
210
+ clim=(128.0, 128.0),
211
+ parent=c.scene)
212
+ rendered = c.render()[..., :3]
213
+
214
+ if num_channels >= 3:
215
+ # RGBs don't have colormaps
216
+ assert rendered.sum() == 0
217
+ return
218
+
219
+ # not all black
220
+ assert rendered.sum() != 0
221
+ # not all white
222
+ assert rendered.sum() != 255 * rendered.size
223
+ # should be all the same value
224
+ r_unique = np.unique(rendered[..., 0])
225
+ g_unique = np.unique(rendered[..., 1])
226
+ b_unique = np.unique(rendered[..., 2])
227
+ assert r_unique.size == 1
228
+ assert g_unique.size == 1
229
+ assert b_unique.size == 1
230
+
231
+
232
+ @requires_application()
233
+ def test_image_vertex_updates():
234
+ """Test image visual coordinates are only built when needed."""
235
+ size = (40, 40)
236
+ with TestingCanvas(size=size, bgcolor="w") as c:
237
+ shape = size + (3,)
238
+ np.random.seed(0)
239
+ image = Image(cmap='grays', clim=[0, 1], parent=c.scene)
240
+ with mock.patch.object(
241
+ image, '_build_vertex_data',
242
+ wraps=image._build_vertex_data) as build_vertex_mock:
243
+ data = np.random.rand(*shape)
244
+ image.set_data(data)
245
+ c.render()
246
+ build_vertex_mock.assert_called_once()
247
+ build_vertex_mock.reset_mock() # reset the count to 0
248
+
249
+ # rendering again shouldn't cause vertex coordinates to be built
250
+ c.render()
251
+ build_vertex_mock.assert_not_called()
252
+
253
+ # changing to data of the same shape shouldn't cause it
254
+ data = np.zeros_like(data)
255
+ image.set_data(data)
256
+ c.render()
257
+ build_vertex_mock.assert_not_called()
258
+
259
+ # changing to another shape should
260
+ data = data[:-5, :-5]
261
+ image.set_data(data)
262
+ c.render()
263
+ build_vertex_mock.assert_called_once()
264
+
265
+
266
+ @requires_application()
267
+ @pytest.mark.parametrize(
268
+ ("dtype", "init_clim"),
269
+ [
270
+ (np.float32, "auto"),
271
+ (np.float32, (0, 5)),
272
+ (np.uint8, "auto"),
273
+ (np.uint8, (0, 5)),
274
+ ]
275
+ )
276
+ def test_change_clim_float(dtype, init_clim):
277
+ """Test that with an image of floats, clim is correctly set from the first try.
278
+
279
+ See https://github.com/vispy/vispy/pull/2245.
280
+ """
281
+ size = (40, 40)
282
+ np.random.seed(0)
283
+ data = (np.random.rand(*size) * 100).astype(dtype)
284
+
285
+ with TestingCanvas(size=size[::-1], bgcolor="w") as c:
286
+ image = Image(data=data, clim=init_clim, parent=c.scene)
287
+
288
+ # needed to properly initialize the canvas
289
+ c.render()
290
+
291
+ image.clim = 0, 10
292
+ rendered1 = c.render()
293
+ # set clim to same values
294
+ image.clim = 0, 10
295
+ rendered2 = c.render()
296
+
297
+ assert np.allclose(rendered1, rendered2)
298
+
299
+
300
+ @requires_application()
301
+ def test_image_interpolation():
302
+ """Test different interpolations"""
303
+ size = (81, 81)
304
+ data = np.array([[0, 1]], dtype=int)
305
+ left = (40, 0)
306
+ right = (40, 80)
307
+ center_left = (40, 39)
308
+ center = (40, 40)
309
+ center_right = (40, 41)
310
+ white = (255, 255, 255, 255)
311
+ black = (0, 0, 0, 255)
312
+ gray = (128, 128, 128, 255)
313
+
314
+ with TestingCanvas(size=size[::-1], bgcolor="w") as c:
315
+ view = c.central_widget.add_view(border_width=0)
316
+ view.camera = PanZoomCamera((0, 0, 2, 1))
317
+ image = Image(data=data, cmap='grays',
318
+ parent=view.scene)
319
+
320
+ # needed to properly initialize the canvas
321
+ render = c.render()
322
+
323
+ image.interpolation = 'nearest'
324
+ render = c.render()
325
+ assert np.allclose(render[left], black)
326
+ assert np.allclose(render[right], white)
327
+ assert np.allclose(render[center_left], black)
328
+ assert np.allclose(render[center_right], white)
329
+
330
+ image.interpolation = 'bilinear'
331
+ render = c.render()
332
+ assert np.allclose(render[left], black)
333
+ assert np.allclose(render[right], white)
334
+ assert np.allclose(render[center], gray, atol=5) # we just want gray, this is not quantitative
335
+
336
+ image.interpolation = 'custom'
337
+ image.custom_kernel = np.array([[0]]) # no sampling
338
+ render = c.render()
339
+ assert np.allclose(render[left], black)
340
+ assert np.allclose(render[right], black)
341
+ assert np.allclose(render[center], black)
342
+
343
+ image.custom_kernel = np.array([[1]]) # same as linear
344
+ render = c.render()
345
+ assert np.allclose(render[left], black)
346
+ assert np.allclose(render[right], white)
347
+ assert np.allclose(render[center], gray, atol=5) # we just want gray, this is not quantitative
348
+
349
+
350
+ @requires_application()
351
+ def test_image_set_data_different_dtype():
352
+ size = (80, 80)
353
+ data = np.array([[0, 127]], dtype=np.int8)
354
+ left = (40, 10)
355
+ right = (40, 70)
356
+ white = (255, 255, 255, 255)
357
+ black = (0, 0, 0, 255)
358
+
359
+ with TestingCanvas(size=size[::-1], bgcolor="w") as c:
360
+ view = c.central_widget.add_view()
361
+ view.camera = PanZoomCamera((0, 0, 2, 1))
362
+ image = Image(data=data, cmap='grays', clim=[0, 127],
363
+ parent=view.scene)
364
+
365
+ render = c.render()
366
+ assert np.allclose(render[left], black)
367
+ assert np.allclose(render[right], white)
368
+
369
+ # same data as float should change nothing
370
+ image.set_data(data.astype(np.float32))
371
+ render = c.render()
372
+ assert np.allclose(render[left], black)
373
+ assert np.allclose(render[right], white)
374
+
375
+ # something inverted, different dtype
376
+ new_data = np.array([[127, 0]], dtype=np.float16)
377
+ image.set_data(new_data)
378
+ render = c.render()
379
+ assert np.allclose(render[left], white)
380
+ assert np.allclose(render[right], black)
381
+
382
+ # out of bounds should clip (2000 > 127)
383
+ new_data = np.array([[0, 2000]], dtype=np.float64)
384
+ image.set_data(new_data)
385
+ render = c.render()
386
+ assert np.allclose(render[left], black)
387
+ assert np.allclose(render[right], white)
388
+
389
+
390
+ run_tests_if_main()
@@ -0,0 +1,36 @@
1
+ from vispy.scene.visuals import ComplexImage
2
+ from vispy.visuals.image_complex import CPU_COMPLEX_TRANSFORMS
3
+ from vispy.testing import requires_application, TestingCanvas
4
+ from vispy.testing.image_tester import downsample
5
+
6
+ import numpy as np
7
+ import pytest
8
+
9
+ from vispy.testing.rendered_array_tester import compare_render
10
+
11
+
12
+ # we add the np.float32 case to test that ComplexImage falls back to Image behavior
13
+ # if the data is not complex
14
+ @requires_application()
15
+ @pytest.mark.parametrize("input_dtype", [np.complex64, np.complex128, np.float32])
16
+ @pytest.mark.parametrize("complex_mode", ["magnitude", "real", "imaginary", "phase"])
17
+ def test_image_complex(input_dtype, complex_mode):
18
+ """Test rendering of complex-valued image data."""
19
+ shape = (40, 40)
20
+ np.random.seed(0)
21
+ data = np.random.random(shape).astype(input_dtype)
22
+ if np.iscomplexobj(data):
23
+ data.imag = np.random.random(shape)
24
+
25
+ with TestingCanvas(size=shape, bgcolor="w") as c:
26
+ ComplexImage(data, cmap="grays", complex_mode=complex_mode, parent=c.scene)
27
+ # render to canvas
28
+ rendered = c.render()
29
+ shape_ratio = rendered.shape[0] // data.shape[0]
30
+ rendered = downsample(rendered, shape_ratio, axis=(0, 1))
31
+
32
+ # perform (auto-clim) rendering on cpu
33
+ exp = CPU_COMPLEX_TRANSFORMS[complex_mode](data) if np.iscomplexobj(data) else data
34
+ exp -= exp.min()
35
+ exp /= exp.max()
36
+ compare_render(exp, rendered)