{"id":15020255,"url":"https://github.com/aplbrain/pytri","last_synced_at":"2025-10-25T10:30:50.195Z","repository":{"id":45850316,"uuid":"106017853","full_name":"aplbrain/pytri","owner":"aplbrain","description":"Python wrapper for Substrate","archived":false,"fork":false,"pushed_at":"2021-12-02T03:48:05.000Z","size":39289,"stargazers_count":4,"open_issues_count":1,"forks_count":2,"subscribers_count":6,"default_branch":"master","last_synced_at":"2024-10-30T01:02:08.205Z","etag":null,"topics":["jhuapl","jupyter-notebook","pytri","substrate","threejs"],"latest_commit_sha":null,"homepage":"https://aplbrain.github.io/pytri/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aplbrain.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-10-06T15:03:36.000Z","updated_at":"2021-12-02T03:48:06.000Z","dependencies_parsed_at":"2022-09-06T13:11:15.745Z","dependency_job_id":null,"html_url":"https://github.com/aplbrain/pytri","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aplbrain%2Fpytri","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aplbrain%2Fpytri/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aplbrain%2Fpytri/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aplbrain%2Fpytri/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aplbrain","download_url":"https://codeload.github.com/aplbrain/pytri/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238120390,"owners_count":19419763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jhuapl","jupyter-notebook","pytri","substrate","threejs"],"created_at":"2024-09-24T19:54:48.767Z","updated_at":"2025-10-25T10:30:49.731Z","avatar_url":"https://github.com/aplbrain.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# pytri v2\n\n\u003e A Pytri redux, using the latest available THREE.js bindings and GPU-offloaded rendering of large scenes.\n\nWARNING: `pytri` is currently untested. Use at your own risk.\n\n## Installation\n\n```shell\npip install pytri\n# or:\n# pip3 install git+https://github.com/aplbrain/pytri\n```\n\n## Getting Started\n\nLet's plot some scatterplot data in 3D. In your favorite Jupyter notebook or binder application, import pytri:\n\n```python\nfrom pytri import Figure\n```\n\nWe can now generate some sample data:\n\n```python\nimport numpy as np\n\nfig = Figure()\n\nxs = np.random.randn(100)\nys = np.random.randn(100)\nzs = np.random.randn(100)\n\nfig.scatter(xs, ys, zs)\n\nfig.show()\n```\n\n\u003cimg width=\"371\" alt=\"image\" src=\"https://user-images.githubusercontent.com/693511/108643342-34765580-7478-11eb-939c-34ead3337a76.png\"\u003e\n\n## Examples\n\n### Render a NetworkX Graph\n\nHere's a crazy dense randomly-arranged graph with over a million edges. (You'll find the slowest part of this process is just generating that graph!)\n\nThis graph renders in realtime (60FPS) in Pytri.\n\n```python\nimport networkx as nx\ng = nx.fast_gnp_random_graph(50_000, 0.001)\npos = {k: [vv * 500 for vv in v] for k, v in nx.random_layout(g, dim=3).items()}\n\nf = Figure()\nf.axes()\nf.graph(g, pos=pos, edge_width=1, node_size=10)\n\nf.show()\n```\n\n\u003cimg width=\"376\" alt=\"image\" src=\"https://user-images.githubusercontent.com/693511/108643454-ad75ad00-7478-11eb-80cf-6e38b829636d.png\"\u003e\n\n### Random color-changing edges\n\nThese edges are a different color on the left edge than on the right edge:\n\n```python\nf = Figure()\nf.axes()\nf.lines(\n    # 100 lines on the interval 0-100\n    np.random.random((100, 2, 3)) * 100,\n    # 200 colors, start/stop for each line\n    colors=np.random.random((100, 2, 3)),\n    width=4\n)\nf.show()\n```\n\n\u003cimg width=\"358\" alt=\"image\" src=\"https://user-images.githubusercontent.com/693511/108643657-7bb11600-7479-11eb-9b71-c406f5f8dadb.png\"\u003e\n\n### Lines and an image pulled from the internet\n\n```python\nf.imshow(\n    \"https://i.imgur.com/VK8Tp5q.jpeg\",\n    width=100, height=100,\n    rotation=(0, 3.14/2, 0)\n)\nf.show()\n```\n\n\u003cimg width=\"383\" alt=\"image\" src=\"https://user-images.githubusercontent.com/693511/108643859-6092d600-747a-11eb-9e7d-b75544a74fc9.png\"\u003e\n\n### Rendering numpy arrays in RGB or Greyscale\n\n```python\nf.scatter(np.random.randint(-50, 50, (1_00_000,3)))\nf.imshow(\n    # 3 dimensions, interpreted as RGB\n    np.random.random((1000, 1000, 3)),\n    width=200, height=200,\n    rotation=(0, 3.14/2, 0)\n)\nf.imshow(\n    # 2 dimensions, interpreted as grayscale\n    np.random.random((1000, 1000)),\n    width=200, height=200,\n    # omitting rotation, the plane faces \"up\" along Z\n)\n```\n\n\u003cimg width=\"500\" alt=\"image\" src=\"https://user-images.githubusercontent.com/693511/108643926-b5365100-747a-11eb-8619-c6686a510f6a.png\"\u003e\n\n### One way to (cheat) render a volume\n\n```python\nfrom pytri import Figure\nimport intern\n\nmorgan2020 = intern.array(\"bossdb://morgan2020/lgn/em\", resolution=2)\n\nem_excerpt = morgan2020[1000:1050, 25000:25000+300, 25000:25000+300]\n\ncoords = []\nfor z in range(em_excerpt.shape[0]):\n    for y in range(em_excerpt.shape[1]):\n        for x in range(em_excerpt.shape[2]):\n            coords.append((x, y, z*10))\n\nf = Figure()\nf.scatter(coords, color=[[i,i,i] for i in em_excerpt.ravel()], attenuate_size=True, size=5)\nf.show()\n```\n\n\u003cimg width=\"410\" alt=\"image\" src=\"https://user-images.githubusercontent.com/693511/108712486-d6338c00-74e4-11eb-945f-4ea2982ddac8.png\"\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faplbrain%2Fpytri","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faplbrain%2Fpytri","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faplbrain%2Fpytri/lists"}