{"id":4686,"library":"plyfile","title":"plyfile","description":"The `plyfile` Python module provides a simple, NumPy-based facility for reading and writing ASCII and binary PLY files, a common format for storing 3D surface meshes. It is currently at version 1.1.3 (released October 21, 2025) and maintains an active development status with several releases per year, as evidenced by its changelog and PyPI activity.","status":"active","version":"1.1.3","language":"en","source_language":"en","source_url":"https://github.com/dranjan/python-plyfile","tags":["PLY","3D","file format","numpy","mesh","graphics"],"install":[{"cmd":"pip install plyfile","lang":"bash","label":"Install latest stable version"}],"dependencies":[{"reason":"Required Python version.","package":"python","optional":false},{"reason":"Underpins data structures for PLY file representation.","package":"numpy","optional":false}],"imports":[{"note":"While `import plyfile` works, directly importing `PlyData` and `PlyElement` is the common and recommended practice for clarity and direct access.","wrong":"import plyfile; plyfile.PlyData","symbol":"PlyData","correct":"from plyfile import PlyData"},{"note":"While `import plyfile` works, directly importing `PlyData` and `PlyElement` is the common and recommended practice for clarity and direct access.","wrong":"import plyfile; plyfile.PlyElement","symbol":"PlyElement","correct":"from plyfile import PlyElement"}],"quickstart":{"code":"import numpy as np\nfrom plyfile import PlyData, PlyElement\nimport os\n\n# 1. Prepare data for a PLY file\nvertices = np.array([\n    (0.0, 0.0, 0.0, 255, 0, 0),\n    (1.0, 0.0, 0.0, 0, 255, 0),\n    (0.0, 1.0, 0.0, 0, 0, 255),\n    (1.0, 1.0, 0.0, 255, 255, 0)\n], dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'), ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])\n\nfaces = np.array([\n    ([0, 1, 2],),\n    ([1, 3, 2],)\n], dtype=[('vertex_indices', 'i4', (3,))])\n\n# 2. Create PlyElement instances\nvertex_element = PlyElement.describe(vertices, 'vertex')\nface_element = PlyElement.describe(faces, 'face')\n\n# 3. Create a PlyData instance\nplydata_to_write = PlyData([vertex_element, face_element], text=True, comments=['Created by plyfile quickstart'])\n\noutput_filename = 'quickstart_output.ply'\n\n# 4. Write the PLY data to a file\nwith open(output_filename, 'wb') as f:\n    plydata_to_write.write(f)\n\nprint(f\"Successfully wrote PLY file: {output_filename}\")\n\n# 5. Read the PLY data from the file\nwith open(output_filename, 'rb') as f:\n    plydata_read = PlyData.read(f)\n\nprint(\"\\nSuccessfully read PLY file:\")\nprint(plydata_read)\nprint(\"Vertices:\\n\", plydata_read['vertex'].data)\nprint(\"Faces:\\n\", plydata_read['face'].data)\n\n# Clean up the created file\nos.remove(output_filename)\nprint(f\"Cleaned up {output_filename}\")","lang":"python","description":"This quickstart demonstrates how to create structured NumPy arrays representing vertices and faces, construct `PlyElement` and `PlyData` objects, write them to an ASCII PLY file, and then read the data back. It covers the basic workflow for both serialization and deserialization."},"warnings":[{"fix":"Upgrade your Python environment to 3.9 or newer and NumPy to 1.21 or newer. `pip install --upgrade python numpy` or manage with your preferred environment tool.","message":"As of `plyfile` version 1.1 (and later), official support for Python versions older than 3.9 and NumPy versions older than 1.21 has been removed. Users on older environments may encounter compatibility issues.","severity":"breaking","affected_versions":">=1.1"},{"fix":"For fixed-length list properties, provide `known_list_len={'element_name': {'list_property_name': length}}` to `PlyData.read`. Avoid memory mapping for elements with truly variable-length list properties.","message":"Memory mapping (`mmap` argument in `PlyData.read`) for faster binary data parsing has limitations with list properties. Elements containing *variable-length* list properties cannot be memory-mapped. For *fixed-length* list properties, the `known_list_len` dictionary argument is mandatory during `PlyData.read` to enable memory mapping.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Always use binary mode (`'rb'` for reading, `'wb'` for writing) when opening PLY files to ensure compatibility with both ASCII and binary PLY formats, unless you specifically intend to work only with ASCII files via text streams.","message":"When performing I/O operations, `plyfile` differentiates between text-mode and binary-mode streams. Text-mode streams (e.g., those returned by `sys.stdin` or `sys.stdout` or `open('file.ply', 'r')`) are only compatible with ASCII-format PLY files. Binary-mode streams (`open('file.ply', 'rb')` or `open('file.ply', 'wb')`) are required for all PLY file formats (ASCII and binary). Writing a binary-format PLY to a text stream will raise a `ValueError`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Ensure that the NumPy structured array dtypes align with supported PLY data types (e.g., float, uchar, int). Convert unsupported types to compatible ones before creating `PlyElement` instances.","message":"When creating PLY files using `plyfile`, there are restrictions on the data types supported by NumPy structured arrays that can be directly mapped to PLY properties. For instance, the PLY format does not directly support 64-bit integer or complex data types. While non-scalar fields are allowed and will be serialized as list properties, users should be mindful of these underlying PLY format limitations.","severity":"gotcha","affected_versions":"All versions"},{"fix":"After reading, if a 2D array is needed from a list property, manually concatenate or stack the individual NumPy arrays stored within the `object`-typed field, e.g., `np.vstack(plydata['element_name'].data['list_property'])`.","message":"When reading a PLY file, even if a non-scalar (e.g., fixed-size array) field was serialized as a list property, `plyfile` will represent it as an `object`-typed field in the NumPy structured array, where each 'object' is itself a NumPy array (e.g., `('vertex_indices', 'O')`). This means list properties are not automatically flattened into a 2D array upon read, requiring manual post-processing if that's the desired format.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-12T00:00:00.000Z","next_check":"2026-07-11T00:00:00.000Z"}