Readers and Writers#
PyVista provides class based readers to have more control over reading
data files. These classes allow for more fine-grained control over
reading datasets from files. See pyvista.get_reader() for a
list of file types supported. The writer classes used by
pyvista.DataObject.save() are listed further down this page.
Also, see Load Data Using a Reader for a full example using reader classes.
|
Get a reader for fine-grained control of reading data files. |
Reading Functions#
These functions read a file in a single call, selecting the reader from
the file extension. To write a file, see save().
|
Extract the extension of the filename. |
|
Read any file type supported by |
|
Read an ExodusII file ( |
|
Read a GRDECL file ( |
|
Load a texture from an image file. |
See also
- Load and Plot From a File
Load and plot a mesh from a file.
- Conversions
Read and write files with
meshio.
Reader Classes#
|
AVSucdReader for .inp files. |
|
BinaryMarchingCubes Reader for .tri files. |
|
BMP Reader for .bmp files. |
|
BYU Reader for .g files. |
|
CGNS Reader for .cgns files. |
|
DEM Reader for .dem files. |
|
DICOM Reader for reading |
|
EnSight Reader for .case files. |
|
Class for enabling and disabling blocks, sets, and block/set arrays in Exodus II files. |
|
ExodusIIReader for .e and .exo files. |
|
Facet Reader for .facet files. |
|
|
|
FluentReader for .cas files. |
|
GambitReader for .neu files. |
|
GaussianCubeReader for .cube files. |
|
GESignaReader for .MR files. |
|
|
|
|
|
|
|
|
|
|
|
JPEG Reader for .jpeg and .jpg files. |
|
Meta Image Reader for .mha and .mhd files. |
|
|
|
MINCImageReader for .mnc files. |
|
MultiBlock Plot3D Reader. |
|
Class for reading .nek5000 files produced by Nek5000 and NekRS. |
|
NIFTI Reader for .nii and .nii.gz files. |
|
|
|
OBJ Reader for reading .obj files. |
|
OpenFOAM Reader for .foam files. |
|
ParticleReader for .raw files. |
|
|
|
PExodusIIReader reads parallel Exodus II and Nemesis files. |
|
Plot3DMeta Reader for .p3d files. |
|
PLY Reader for reading .ply files. |
|
|
|
|
|
Parallel OpenFOAM Reader for .foam files. |
|
ProStarReader for .vrt files. |
|
|
|
PVD Reader for .pvd files. |
|
SegYReader for .sgy and .segy files. |
|
Class for reading .series file supported by ParaView. |
|
|
|
STL Reader for .stl files. |
|
Tecplot Reader for ascii .dat files. |
|
ThreeDSReader for .3ds files. |
|
|
|
|
|
VTK Data Set Reader for .vtk files. |
|
Parallel VTK Data Set Reader for .pvtk files. |
|
XdmfReader for .xdmf files. |
|
XML Image Data Reader for .vti files. |
|
XML MultiBlock Data Reader for .vtm or .vtmb files. |
|
XML PartitionedDataSet Reader for reading .vtpd files. |
|
Parallel XML Image Data Reader for .pvti files. |
|
XML PolyData Reader for .vtp files. |
|
Parallel XML RectilinearGrid Reader for .pvtr files. |
|
Parallel XML UnstructuredGrid Reader for .pvtu files. |
|
XML RectilinearGrid Reader for .vtr files. |
|
XML StructuredGrid Reader for .vts files. |
|
XML UnstructuredGrid Reader for .vtu files. |
Custom Readers#
Third-party packages can register custom readers so that
pyvista.read() handles additional file formats automatically.
Registration can be done programmatically or via Python entry points
for zero-config discovery at install time.
- register_reader( ) Callable[[_T_Provider], _T_Provider] | None[source]#
Register a custom reader for a file extension.
Can be used as a plain call or as a decorator.
Two kinds of reader may be registered:
A
BaseReadersubclass. This is the preferred form. The class is resolved bypyvista.get_reader()exactly like a built-in reader, so keyword arguments passed topyvista.read()set reader attributes,progress_barandvalidateare honored, VTK error observers are attached, and mixins such asTimeReaderandPointCellDataSelectionwork unchanged.A bare callable
handler(path, **kwargs). This is the lighter form for a format that has no reader-level state to expose.pyvista.read()calls it directly;pyvista.get_reader()raisesValueErrorfor the extension because there is no reader object to hand back.
Added in version 0.48.0.
Changed in version 0.49.0:
handlermay be aBaseReadersubclass.- Parameters:
- key
str A file extension (for example,
'.myformat').- handler
callable()ortype[pyvista.BaseReader],optional A
BaseReadersubclass, or a callable with signaturehandler(path: str, **kwargs)that returns apyvista.DataSet. When omitted the function acts as a decorator and returns the decorated object unchanged.- overridebool, default:
False If
True, allow overriding a built-in VTK reader for this extension and silence the warning that would otherwise fire when replacing an existing custom registration. The equivalent for a plugin discovered through entry points is to declare the entry point in thepyvista.readers.overridegroup rather thanpyvista.readers.
- key
- Returns:
callable()orNoneWhen used as a decorator (
handleromitted), returns the decorated function or class. Otherwise returnsNone.
- Raises:
ValueErrorIf
keycollides with a built-in VTK reader andoverrideisFalse.
- Warns:
UserWarningIf
keyalready refers to a registered custom reader. The new registration replaces the old one (last wins); passoverride=Trueto silence the warning.
Examples#
Download Python source code | Download Jupyter notebook
Register a reader for a custom file extension.
>>> import pyvista as pv >>> def my_reader(path, **kwargs): ... >>> pv.register_reader('.myformat', my_reader)
Use as a decorator.
>>> @pv.register_reader('.myotherformat') ... def my_reader(path, **kwargs): ...
Register a
BaseReadersubclass so thatpyvista.get_reader()resolves the extension too. Where VTK has no reader for the format,BaseVTKReadersupplies the parsing half.>>> class _MyVTKReader(pv.BaseVTKReader): ... def UpdateInformation(self): ... ... def Update(self): ... self._data_object = pv.PolyData() >>> @pv.register_reader('.mybinaryformat') ... class MyReader(pv.BaseReader): ... _class_reader = _MyVTKReader
See Also#
pyvista.register_writerSibling API for registering custom writers.
pyvista.registered_readersIntrospect every registered reader.
pyvista.get_readerResolves registered
BaseReadersubclasses.
- registered_readers() tuple[ReaderRegistration, ...][source]#
Return every custom reader currently registered.
Forces discovery of any pending entry-point plugins so the returned list reflects every reader visible to PyVista. A plugin that fails to import emits a
UserWarningand is skipped; the rest still appear in the result.This is the call to reach for when a built-in format reads differently than expected: a record whose
overrideisTruenames the plugin that took the extension over, and itssourcesays where that plugin came from.Added in version 0.48.0.
Changed in version 0.49.0: Records carry
reader_classandoverride.- Returns:
tuple[ReaderRegistration, …]One record per registered extension. Each record exposes
extension,handler,source,reader_class, andoverride.
Examples#
Download Python source code | Download Jupyter notebook
>>> import pyvista as pv >>> def my_reader(path, **kwargs): ... >>> pv.register_reader('.demo_reader', my_reader) >>> [ ... r.extension ... for r in pv.registered_readers() ... if r.extension == '.demo_reader' ... ] ['.demo_reader']
- class ReaderRegistration(
- extension: str,
- handler: ReaderProvider,
- source: str,
- reader_class: bool = False,
- override: bool = False,
Describe one registered custom reader.
Returned by
registered_readers().Added in version 0.48.0.
- Attributes:
- extension
str File extension the reader is registered against, including the leading dot (for example,
'.myformat').- handler
callable()ortype[pyvista.BaseReader] The reader callable, or the
BaseReadersubclass when the extension was registered with a reader class.- source
str Human-readable origin in the form
'module.qualname'for explicit registrations or the entry-pointvaluefor plugin-discovered registrations.- reader_classbool
Truewhenhandleris aBaseReadersubclass, meaningpyvista.get_reader()resolves this extension as well aspyvista.read().Added in version 0.49.0.
- overridebool
Truewhen this reader replaces one PyVista ships, either throughregister_reader(..., override=True)or through thepyvista.readers.overrideentry-point group. Check this first when a built-in format reads differently than expected: it names the plugin that took the extension over.Added in version 0.49.0.
- extension
Two forms of reader
A registration is either a plain callable or a
pyvista.BaseReader subclass, and the choice decides how much
of PyVista’s reader machinery the format gets:
Capability |
Callable |
|
|---|---|---|
yes |
yes |
|
no |
yes |
|
Keyword arguments to |
dropped |
set as reader attributes |
|
ignored |
honored |
unavailable |
available |
A callable is the lighter option and is the right choice for a format
with no reader-level state to expose. Register a
pyvista.BaseReader subclass for anything a user will want to
configure, step through in time, or select arrays from.
To write a reader class for a format VTK has no reader for, subclass
pyvista.BaseVTKReader for the parsing and point a
pyvista.BaseReader subclass at it:
import pyvista as pv
class _MyVTKReader(pv.BaseVTKReader):
def UpdateInformation(self):
pass
def Update(self):
self._data_object = _parse(self._filename)
@pv.register_reader('.myformat')
class MyReader(pv.BaseReader):
_class_reader = _MyVTKReader
Entry points
Packages can also register readers in pyproject.toml so they are
discovered automatically when installed. The entry-point value may name
either a callable or a pyvista.BaseReader subclass:
[project.entry-points."pyvista.readers"]
".myformat" = "my_package:read_my_format"
".myotherformat" = "my_package:MyOtherReader"
Replacing a built-in reader
An entry point in the pyvista.readers group may only claim an
extension PyVista does not already read. Claiming one it does
(.vtp, .stl, .ply) would silently change what every
pyvista.read() call in the environment returns, so PyVista
refuses and raises ValueError naming the package, the built-in
reader, and this section.
To replace a built-in reader on purpose, declare the entry point in the
pyvista.readers.override group instead. The two groups are
identical except that the override group is permitted to take an
extension PyVista ships a reader for, and does so silently:
[project.entry-points."pyvista.readers.override"]
".vtp" = "my_package:MyPolyDataReader"
This is the entry-point equivalent of override=True on
pyvista.register_reader(). Both groups accept both forms, a
callable or a pyvista.BaseReader subclass.
Declaring an override for an extension PyVista does not currently read is allowed and silent. It costs nothing and keeps the package working if a later PyVista release adds a reader for that extension.
Because an override changes the meaning of a format the user did not
choose, it is visible from pyvista.registered_readers(): the
record for the extension reports override=True along with the
source that claimed it. That is the first call to make when a
built-in format reads differently than expected.
import pyvista as pv
taken = [
(r.extension, r.source)
for r in pv.registered_readers()
if r.override
]
# [('.vtp', 'my_package:MyPolyDataReader')]
Remote URI support
When pyvista.read() is given a remote URI (https://,
s3://, etc.) and a custom reader is registered for the file
extension, the URI is passed directly to the reader. If the reader
raises LocalFileRequiredError, PyVista downloads
the file to a temporary local path and retries. For built-in
formats with no custom reader, the download happens automatically.
This uses fsspec when available (install with
pip install pyvista[io]), falling back to pooch for HTTP(S)
URIs.
- class LocalFileRequiredError[source]#
Raise from a registered reader to signal it needs a local file path.
When
pyvista.read()passes a remote URI to a custom reader and the reader raises this exception, PyVista will download the file to a temporary local path and retry the reader automatically.Examples#
Download Python source code | Download Jupyter notebook
>>> import pyvista as pv >>> from pyvista.core.utilities.reader_registry import LocalFileRequiredError >>> @pv.register_reader('.myremoteformat') ... def my_reader(path, **kwargs): ... if '://' in path: ... raise LocalFileRequiredError ... ...
Custom Writers#
Third-party packages can register custom writers so that
pyvista.DataObject.save() handles additional file formats
automatically. Registration mirrors pyvista.register_reader()
and supports programmatic calls, decorators, and Python entry points
for zero-config discovery at install time.
- register_writer( ) Callable[[WriterHandler], WriterHandler] | None[source]#
Register a custom writer for a file extension.
Can be used as a plain call or as a decorator.
Added in version 0.48.0.
- Parameters:
- key
str A file extension (for example,
'.myformat').- handler
callable(),optional A callable with signature
handler(dataset, path, **kwargs)that writesdatasettopath. Any extra keyword arguments passed topyvista.DataObject.save()are forwarded to the handler as**kwargs—use them to expose format-specific options such as compression level, thread count, or chunking. Handlers that do not need per-call options can omit**kwargs; a call tosave()that passes extras to such a handler will raiseTypeErrorfrom Python itself. Whenhandleris omitted the function acts as a decorator and returns the decorated callable unchanged.- overridebool, default:
False If
True, allow overriding a built-in PyVista writer for this extension and silence the warning that would otherwise fire when replacing an existing custom registration.
- key
- Returns:
callable()orNoneWhen used as a decorator (
handleromitted), returns the decorated function. Otherwise returnsNone.
- Raises:
ValueErrorIf
keycollides with a built-in PyVista writer andoverrideisFalse.
- Warns:
UserWarningIf
keyalready refers to a registered custom writer. The new registration replaces the old one (last wins); passoverride=Trueto silence the warning.
Notes#
When
pyvista.DataObject.save()is called, registered custom writers are dispatched before built-in VTK writers—mirroring the dispatch order ofpyvista.read(). Passingoverride=Trueis therefore the only way to replace a built-in writer at save time.Any keyword arguments passed to
save()beyond its documented parameters are forwarded verbatim to the registered handler. When no custom writer is registered for the target extension, extra keyword arguments raiseTypeErrorfromsave()—PyVista never silently drops writer options.Examples#
Download Python source code | Download Jupyter notebook
Register a writer for a custom file extension with a format-specific option.
>>> import pyvista as pv >>> def my_writer(dataset, path, *, level=3): ... >>> pv.register_writer('.myformat', my_writer) >>> pv.Sphere().save('sphere.myformat', level=9)
Use as a decorator.
>>> @pv.register_writer('.myformat') ... def my_writer(dataset, path, **kwargs): ...
See Also#
pyvista.register_readerSibling API for registering custom readers.
pyvista.registered_writersIntrospect every registered writer.
- registered_writers() tuple[WriterRegistration, ...][source]#
Return every custom writer currently registered.
Forces discovery of any pending entry-point plugins so the returned list reflects every writer visible to PyVista. A plugin that fails to import emits a
UserWarningand is skipped; the rest still appear in the result.Added in version 0.48.0.
- Returns:
tuple[WriterRegistration, …]One record per registered extension. Each record exposes
extension,handler, andsource.
Examples#
Download Python source code | Download Jupyter notebook
>>> import pyvista as pv >>> def my_writer(dataset, path, **kwargs): ... >>> pv.register_writer('.demo_writer', my_writer) >>> [ ... r.extension ... for r in pv.registered_writers() ... if r.extension == '.demo_writer' ... ] ['.demo_writer']
- class WriterRegistration(extension: str, handler: WriterHandler, source: str)[source]#
Describe one registered custom writer.
Returned by
registered_writers().Added in version 0.48.0.
- Attributes:
- extension
str File extension the writer is registered against, including the leading dot (for example,
'.myformat').- handler
callable() The writer callable.
- source
str Human-readable origin in the form
'module.qualname'for explicit registrations or the entry-pointvaluefor plugin-discovered registrations.
- extension
Handler signature
A writer handler is a callable handler(dataset, path, **kwargs)
that writes dataset to path. Any extra keyword arguments passed
to pyvista.DataObject.save() beyond its documented parameters
are forwarded verbatim to the handler as **kwargs. Use them to
expose format-specific options such as compression level, thread
count, or chunking. When no custom writer is registered for the
target extension, passing extra keyword arguments to
save() raises TypeError; PyVista
never silently drops writer options.
Entry points
Packages can register writers in pyproject.toml so they are
discovered automatically when installed:
[project.entry-points."pyvista.writers"]
".myformat" = "my_package:write_my_format"
Dispatch order
When save() is called, custom writers
registered via pyvista.register_writer() are dispatched before
built-in VTK writers for the same extension, mirroring the dispatch
order used by pyvista.read(). By default, registering a
handler for an extension that collides with a built-in PyVista writer
raises ValueError; pass override=True to replace the
built-in writer.
The .pv Format: PyVista’s Native Binary Format#
PyVista has a native zstd-compressed binary format with the
.pv extension, implemented by the
pyvista-zstd companion
package. It is a compact, multi-threaded format for fast dataset
I/O and is included in the io extra:
pip install pyvista[io]
Once installed, .pv round-trips “just work” via the
pyvista.readers and pyvista.writers entry-point hooks
without any manual registration:
import pyvista as pv
mesh = pv.Sphere()
mesh.save('sphere.pv')
pv.read('sphere.pv')
Without it, both pyvista.read() and
pyvista.DataObject.save() raise ImportError naming the
package and the install command; see Optional Formats below.
Supported dataset types include ImageData,
PolyData, StructuredGrid,
RectilinearGrid, UnstructuredGrid,
MultiBlock, and
ExplicitStructuredGrid. The format uses zstd
compression with multi-threaded encode/decode and is a good choice
over .vtu / .vtp / .vtm when file size or I/O latency
matters.
Optional Formats#
A few formats are served by companion packages rather than by PyVista
itself, so that a heavyweight or narrowly used codec is not carried by
every install. PyVista still knows the extension: pyvista.read()
and pyvista.DataObject.save() dispatch to the companion package
when it is installed, and raise ImportError naming the package
and the install command when it is not.
Extension |
Format |
Direction |
Package |
|---|---|---|---|
|
CalculiX FRD result files |
read |
|
|
PyVista’s native |
read, write |
All of them are included in the io extra:
pip install pyvista[io]
Reading and saving are then transparent:
import pyvista as pv
mesh = pv.read('mesh.frd')
mesh.save('mesh.pv')
Without the package, the extension is still recognized: the
ImportError names the format, the missing package, and both
the pip install pyvista[io] command and the command for that one
package on its own. When the package is present but fails to import,
the error reports the import failure instead, with no install command.
These packages provide the reader object themselves, so
pyvista.get_reader() does not resolve their extensions. Use the
package’s own reader class when reader-level control such as time-step
selection is needed:
import pyvista_frd
reader = pyvista_frd.FRDReader('mesh.frd')
reader.set_active_time_value(reader.time_values[-1])
mesh = reader.read()
The error pyvista.get_reader() raises names that class, so it
says where to go: pyvista_frd.FRDReader for .frd and
pyvista_zstd.Reader for .pv.
Keyword arguments beyond those save()
documents are forwarded to the package’s writer, so format-specific
options are reachable without a separate import:
mesh.save('mesh.pv', level=19, n_threads=4)
Changed in version 0.49.0: .frd moved from a built-in reader to pyvista-frd-reader.
pyvista.FRDReader was removed; use pyvista_frd.FRDReader.
Faster Readers for Built-in Formats#
Two further companion packages read a format PyVista already supports,
faster than the VTK reader does. They declare the
pyvista.readers.override entry point described above, so installing
one is all it takes for pyvista.read() to use it.
Extension |
Format |
Package |
|---|---|---|
|
Polygon File Format |
|
|
Stereolithography |
Both ship in the io-override extra, which is intentionally separate
from io because installing it changes the readers used for existing
formats:
pip install pyvista[io-override]
The packages aim to match the stock VTK readers, including point normals,
texture coordinates, and colors, but their behavior and output are not
guaranteed to be identical. Neither is required: without them
pyvista.read() falls back to pyvista.PLYReader and
pyvista.STLReader, which also remain what
pyvista.get_reader() hands back.
Because an override changes a format the user did not choose,
pyvista.registered_readers() reports it:
import pyvista as pv
[(r.extension, r.source) for r in pv.registered_readers() if r.override]
# [('.ply', 'pyvista_miniply:read_as_mesh'), ('.stl', 'pyvista_stl:read_as_mesh')]
To read a file with the VTK reader while a package is installed, use the reader class directly:
mesh = pv.STLReader('mesh.stl').read()
Added in version 0.49.0.
Writer Classes#
PyVista provides built-in writer classes for saving datasets to various file
formats. These are used internally by pyvista.DataObject.save().
|
The base writer class. |
|
|
|
DataSetWriter for VTK legacy dataset files |
|
EnSightWriter for |
|
|
|
HoudiniPolyDataWriter for Houdini geometry |
|
|
|
|
|
NIFTIImageWriter for |
|
|
|
|
|
|
|
|
|
PolyDataWriter for legacy VTK PolyData |
|
RectilinearGridWriter for legacy VTK rectilinear grid |
|
SimplePointsWriter for simple point-set |
|
|
|
StructuredGridWriter for legacy VTK structured grid |
|
|
|
UnstructuredGridWriter for legacy VTK unstructured grid |
|
XMLImageDataWriter for VTK XML image data |
|
XMLMultiBlockDataWriter for VTK XML multiblock |
|
XMLPartitionedDataSetWriter for VTK XML partitioned datasets |
|
XMLPolyDataWriter for VTK XML polydata |
|
XMLRectilinearGridWriter for VTK XML rectilinear grid |
|
XMLStructuredGridWriter for VTK XML structured grid |
|
XMLUnstructuredGridWriter for VTK XML unstructured grid |
Inherited Classes#
The pyvista.BaseReader is inherited by all sub-readers. It
has the basic functionality of all readers to set filename and read
the data.
The PointCellDataSelection is inherited by readers that
support inspecting and setting data related to point and cell arrays.
The TimeReader is inherited by readers that support inspecting
and setting time or iterations for reading.
The BaseVTKReader is the base for a reader implemented in pure
Python rather than by a VTK reader class. Subclass it, implement
UpdateInformation and Update, and point a
pyvista.BaseReader subclass at it through _class_reader.
This is how pyvista.PVDReader and pyvista.GIFReader
are built, and it is the supported base for a third-party reader
registered with pyvista.register_reader().
The remaining classes are not used directly. They are documented because they define members shared by several readers and writers, so that each of those members is documented once and linked from every class that inherits it.
|
The Base Reader class. |
Simulate a VTK reader. |
|
Add a |
|
|
Base class for readers and writers, which are matched to files by extension. |
|
|
|
Class for storing dataset info from PVD file. |
|
Class for storing dataset info from series file. |
Abstract class for readers supporting time. |
|
|
Base class for the XML writers, which also support compression. |
Enumerations#
Enumerations are available to simplify inputs to certain readers.