tl; dr: Я не думаю, что вы должны пытаться использовать для этого matplotlib, и это будет сложно и не очень хорошо работает. Я предлагаю использовать выделенную библиотеку vtk, либо vtk
, либо более высокий уровень mayavi.mlab
. Я подробно остановлюсь на этом.
Данные
Во-первых, вот небольшая, автономная версия ваших входных данных (поскольку данные, которые вы связали в вопросе, слишком велики и могут рано или поздно стать неработающей ссылкой). Я сократил ваши данные до трех прямоугольных кубоидов различных размеров, чтобы приблизиться к вашей фигуре.
# vtk DataFile Version 3.1
MCVE VTK file
ASCII
DATASET UNSTRUCTURED_GRID
POINTS 16 float
0. 0. 0.
0. 0. 3.
0. 2. 0.
0. 2. 3.
4. 0. 0.
4. 0. 3.
4. 2. 0.
4. 2. 3.
5. 0. 0.
5. 0. 3.
5. 2. 0.
5. 2. 3.
13. 0. 0.
13. 0. 3.
13. 2. 0.
13. 2. 3.
CELLS 3 27
8 0 1 3 2 4 5 7 6
8 4 5 7 6 8 9 11 10
8 8 9 11 10 12 13 15 14
CELL_TYPES 3
12 12 12
CELL_DATA 3
SCALARS elem_val float
LOOKUP_TABLE default
1
2
3
Давайте обсудим, что представляет этот файл. Заголовок указывает, что это неструктурированная сетка. Это означает, что он может содержать точки, расположенные произвольным образом. В основном мешок очков. Вы можете найти некоторые пояснения по поводу формата файла здесь .
Первый блок, POINTS
, содержит строки 16 float
, каждая строка соответствует координатам точки в 3d, всего 16 точек.
Второй блок, CELLS
, определяет 3 строки, каждая строка соответствует ячейке (меньшая единица, в данном случае объем), определенной в виде основанных на 0 индексов точек. Первое число (8
) указывает количество вершин в данной ячейке, следующие числа являются индексами точек для соответствующих вершин. Все три ячейки в приведенном выше примере файла данных состоят из 8 вершин, поскольку каждый кубоид, который мы хотим нарисовать, имеет 8 вершин. Второе число в строке CELLS
- это общее количество чисел в этом блоке, т. Е. 3 * (8+1)
, т. Е. 27.
Третий блок, CELL_TYPES
, определяет тип ячейки для каждой из 3
ячеек. В этом случае все они имеют тип 12
, что соответствует «шестигранникам». Информативная цифра заимствована из рис. 2 из уже связанных примеров :
Здесь перечислены основные типы типов ячеек и соответствующие им индексы.
Последний блок, SCALARS
, содержит скаляр (число) для каждой ячейки, в соответствии с которым она будет окрашена позже. Скаляры от 1
до 3
будут отображены в цветовую карту, чтобы дать вам красно-синий переход, видимый на вашей фигуре.
Почему бы не matplotlib?
Я не знаком с meshio
, но подозреваю, что он дает вам доступ к вышеупомянутым блокам в файле VTK. Атрибут mesh.cells
, который вы показали, предполагает, что он распознает, что каждая ячейка является «шестигранником», и перечисляет каждую ячейку и соответствующие ей 8 индексов вершин. Атрибут mesh.points
, вероятно, является массивом формы (n,3)
, и в этом случае mesh.points[cell_inds, :]
дает вам (8,3)
-образные координаты данной ячейки, определенной ее массивом из 8 длин cell_inds
.
Как бы вы визуализировали это с помощью matplotlib? Во-первых, ваши фактические данные огромны, они содержат 84480 ячеек, хотя издалека они выглядят очень похоже на мои данные выше. Так что вам придется
- придумали способ превратить все эти координаты ячейки в поверхности, которые должны быть нанесены с помощью matplotlib, что было бы нелегко,
- затем осознайте, что 80k-поверхности приведут к огромным затратам памяти и процессора в matplotlib, наконец
- обратите внимание, что у matplotlib есть 2d рендерер, поэтому 3d визуализация сложных (читай: разъединяющих, сцепляющихся) поверхностей часто искажается .
Учитывая все вышесказанное, я бы определенно не пытался использовать для этого matplotlib.
Что тогда?
Используйте то, что ParaView использует под капотом: VTK! Вы по-прежнему можете использовать оборудование программно через модуль низкого уровня vtk
или модуль высокого уровня (er) mayavi.mlab
. Есть также mayavi
-связанный модуль tvtk
, который является своего рода средним уровнем (это все еще низкоуровневый VTK для этих целей, но с более дружественным для Python API), но я оставлю это как упражнение читателю.
1. vtk
Чтение и построение неструктурированной сетки с помощью vtk немного сложнее (как это всегда бывает с голым vtk, поскольку вы должны собрать конвейер самостоятельно), но управляемым с помощью этой древней вики-страницы плюс эти исправления, которые изменились с :
from vtk import (vtkUnstructuredGridReader, vtkDataSetMapper, vtkActor,
vtkRenderer, vtkRenderWindow, vtkRenderWindowInteractor)
file_name = "mesh_mcve.vtk" # minimal example vtk file
# Read the source file.
reader = vtkUnstructuredGridReader()
reader.SetFileName(file_name)
reader.Update() # Needed because of GetScalarRange
output = reader.GetOutput()
output_port = reader.GetOutputPort()
scalar_range = output.GetScalarRange()
# Create the mapper that corresponds the objects of the vtk file
# into graphics elements
mapper = vtkDataSetMapper()
mapper.SetInputConnection(output_port)
mapper.SetScalarRange(scalar_range)
# Create the Actor
actor = vtkActor()
actor.SetMapper(mapper)
# Create the Renderer
renderer = vtkRenderer()
renderer.AddActor(actor)
renderer.SetBackground(1, 1, 1) # Set background to white
# Create the RendererWindow
renderer_window = vtkRenderWindow()
renderer_window.AddRenderer(renderer)
# Create the RendererWindowInteractor and display the vtk_file
interactor = vtkRenderWindowInteractor()
interactor.SetRenderWindow(renderer_window)
interactor.Initialize()
interactor.Start()
Обратите внимание, что я только минимально изменил оригинальную версию вики. Вот вывод после некоторого поворота окна просмотра:
![output using vtk module, bar with red, green and blue stripe](https://i.stack.imgur.com/jYc0D.png)
Фактический цвет зависит от цветовой карты по умолчанию и масштабирования скаляров. Приведенное выше значение по умолчанию для модуля vtk
, по-видимому, использует цветовую карту jet
по умолчанию, и оно нормализует скаляры, так что значения отображаются в полный цветовой диапазон.
2. mayavi.mlab
Лично я считаю vtk
огромной болью в использовании. Он включает в себя много поиска и чаще всего копание в лабиринте подмодулей и классов, определенных в библиотеке. Вот почему я всегда стараюсь использовать vtk
через высокоуровневую функциональность mayavi.mlab
. Этот модуль особенно полезен, когда вы не работаете с файлами VTK (например, когда пытаетесь визуализировать данные, которые определены в массивах numpy), но в данном случае это также избавляет нас от большой работы , обеспечивая при этом дополнительную функциональность. Вот та же визуализация с использованием mlab
:
from mayavi import mlab
from mayavi.modules.surface import Surface
file_name = "mesh_mcve.vtk" # minimal example vtk file
# create a new figure, grab the engine that's created with it
fig = mlab.figure()
engine = mlab.get_engine()
# open the vtk file, let mayavi figure it all out
vtk_file_reader = engine.open(file_name)
# plot surface corresponding to the data
surface = Surface()
engine.add_filter(surface, vtk_file_reader)
# block until figure is closed
mlab.show()
Гораздо меньше работы! Мы вытолкнули всю чудовищность разбора VTK на mayavi
вместе с беспорядком картографов, актеров, рендеров и ...
Вот как это выглядит:
![output with mlab, similar three-coloured bar but the colours are in reverse order](https://i.stack.imgur.com/t32Ur.png)
Выше приведена минимальная визуализация с минимальными усилиями, но отсюда, конечно, вы можете начать изменять то, что вам нравится, чтобы оно соответствовало вашим потребностям. Вы можете изменить фон, изменить цветовую карту, манипулировать данными странным образом, вы называете это. Обратите внимание, что цвета здесь перевернуты по сравнению со случаем vtk
, поскольку либо цветовая карта по умолчанию, либо отображение скаляров на цветовую карту (справочную таблицу) отличается. Чем больше вы отклоняетесь от высокоуровневого API mlab, тем грязнее оно становится (поскольку вы все ближе и ближе подходите к голому VTK под капотом), но обычно вы все равно можете сэкономить много работы и запутанный код с помощью mayavi
.
Наконец, окно рисунков mayavi
поддерживает все виды драгоценных камней: интерактивное изменение конвейера и сцены, аннотации, такие как оси координат, переключение ортогональных проекций и даже возможность записывать все, что вы изменяете в интерактивном режиме, в автоматически сгенерированном виде. скрипты на питоне. Я бы определенно предложил попробовать реализовать то, что вы хотите сделать, используя Mayavi. Если вы знаете, что будете делать с ParaView, довольно просто перенести его на mayavi
, используя его интерактивную функцию записи сеансов.