杰瑞科技汇

Python Mayavi如何生成PDF可视化?

Of course. This is an excellent question because combining Mayavi for 3D visualization with PDFs for report generation is a very powerful workflow in science and engineering.

Python Mayavi如何生成PDF可视化?-图1
(图片来源网络,侵删)

Here’s a comprehensive guide covering different methods, from the most common to more advanced techniques.

Summary of Methods

Method Best For Pros Cons
Matplotlib Backend Quick plots, compatibility with Matplotlib Easy to use, familiar API Mayavi features might be limited
Save as Image High-quality static figures Full Mayavi power, simple Not vector-based (can pixelate when scaled)
E-Links (Vector Graphics) High-quality, scalable figures in PDFs Vector format, looks perfect at any size More complex setup, requires svg2pdf
Interactive Embedding Dynamic reports (Jupyter, Qt) Interactive 3D plots in the PDF Requires PDF reader with JavaScript support

Method 1: Using the Matplotlib Backend (Easiest)

Mayavi can be used as a backend for Matplotlib. This is the simplest way to get a Mayavi plot into a Matplotlib figure, which can then be saved directly to a PDF.

How it works: You configure Matplotlib to use mayavi.mlab as its plotting engine and then use standard Matplotlib commands.

Example Code:

Python Mayavi如何生成PDF可视化?-图2
(图片来源网络,侵删)
import numpy as np
from mayavi import mlab
import matplotlib.pyplot as plt
# 1. Configure Matplotlib to use the Mayavi backend
mlab.options.backend = 'matplotlib'
# 2. Create a figure using Matplotlib
fig = plt.figure(figsize=(8, 6))
# 3. Plot using Mayavi's mlab functions
# The plot will be drawn on the Matplotlib figure
x, y = np.mgrid[-3:3:100j, -3:3:100j]
z = np.sin(x**2 + y**2) / (x**2 + y**2)
# The 'figure' keyword tells mlab which Matplotlib figure to use
mlab.surf(z, warp_scale='auto', figure=fig)
mlab.xlabel('X axis')
mlab.ylabel('Y axis')
mlab.zlabel('Z axis')"Mayavi Plot in Matplotlib Figure")
# 4. Save the Matplotlib figure to a PDF
# This will save the Mayavi plot as a raster image within the PDF
plt.savefig('mayavi_matplotlib.pdf', dpi=300, bbox_inches='tight')
print("Saved mayavi_matplotlib.pdf")
# To display the plot (optional)
# plt.show()

Pros:

  • Very straightforward if you already know Matplotlib.
  • A single savefig call is all you need.

Cons:

  • The plot is saved as a raster (image) inside the PDF, not as a vector graphic. This means it can appear pixelated if you zoom in or print at a high resolution.
  • You lose some of Mayavi's advanced interactive features when embedded this way.

Method 2: Save as Image and Embed (Common & Practical)

This is a very common and effective workflow. You generate the plot with Mayavi, save it as a high-resolution image (PNG, TIFF, etc.), and then embed that image into a PDF using a library like reportlab or PyPDF2.

Example Code:

import numpy as np
from mayavi import mlab
from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Image, Paragraph
from reportlab.lib.styles import getSampleStyleSheet
# --- Step 1: Generate and save the Mayavi plot as an image ---
print("Generating Mayavi plot...")
x, y = np.mgrid[-3:3:100j, -3:3:100j]
z = np.sin(x**2 + y**2) / (x**2 + y**2)
# Create a new figure window
fig = mlab.figure(size=(800, 600))
mlab.surf(z, warp_scale='auto')
mlab.xlabel('X axis')
mlab.ylabel('Y axis')
mlab.zlabel('Z axis')"Mayavi Plot as Embedded Image")
# Save the figure to a high-quality image file
# Use a high DPI for better quality in the PDF
mlab.savefig('mayavi_plot.png', size=(800, 600))
print("Saved mayavi_plot.png")
# Close the Mayavi figure to free resources
mlab.close(fig)
# --- Step 2: Create a PDF and embed the image ---
print("Creating PDF...")
doc = SimpleDocTemplate("report_with_image.pdf", pagesize=letter)
styles = getSampleStyleSheet()
Story = []
# Add a title paragraph= Paragraph("<b>My Scientific Report</b>", styles['h1'])
Story.append(p_title)
# Add some text
p_text = Paragraph("This report contains a 3D surface plot generated with Mayavi. "
                   "The plot was saved as a PNG and embedded into this PDF.", styles['Normal'])
Story.append(p_text)
# Add the image
# You can specify width/height to scale it
try:
    im = Image("mayavi_plot.png", width=500, height=375)
    Story.append(im)
except Exception as e:
    print(f"Could not embed image: {e}")
# Build the PDF
doc.build(Story)
print("Saved report_with_image.pdf")

Pros:

  • Simple to implement.
  • You get the full power and quality of Mayavi's rendering engine.
  • You have full control over the final PDF layout using libraries like reportlab.

Cons:

  • The plot is still a raster image, not a scalable vector graphic.

Method 3: Save as E-Links (Vector Graphics - Highest Quality)

This is the most advanced method and produces the highest-quality results. It involves saving the Mayavi plot as a vector graphic format (like SVG) and then converting it to a format that can be embedded as a vector in a PDF (like PDF or EPS via inkscape or svg2pdf).

How it works:

  1. Save the Mayavi scene as an SVG file.
  2. Use a command-line tool (like inkscape) or a Python library to convert the SVG to a PDF.
  3. Embed this new vector PDF into your final report PDF.

Example Code:

import numpy as np
from mayavi import mlab
import subprocess
import os
# --- Step 1: Generate and save the Mayavi plot as an SVG ---
print("Generating Mayavi plot as SVG...")
x, y = np.mgrid[-3:3:100j, -3:3:100j]
z = np.sin(x**2 + y**2) / (x**2 + y**2)
mlab.surf(z, warp_scale='auto')
mlab.xlabel('X axis')
mlab.ylabel('Y axis')
mlab.zlabel('Z axis')"Mayavi Plot as Vector Graphic")
# Save as SVG
mlab.savefig('mayavi_plot.svg')
print("Saved mayavi_plot.svg")
# Close the Mayavi figure
mlab.close(fig)
# --- Step 2: Convert SVG to PDF using Inkscape ---
# Make sure Inkscape is installed and in your system's PATH.
# On Ubuntu/Debian: sudo apt-get install inkscape
# On macOS (with Homebrew): brew install --cask inkscape
# On Windows: Download from Inkscape.org and add to PATH.
svg_file = 'mayavi_plot.svg'
pdf_file_vector = 'mayavi_plot_vector.pdf'
try:
    # Use Inkscape to convert SVG to PDF
    # The '--export-pdf' flag specifies the output format
    subprocess.run(['inkscape', '--export-pdf=' + pdf_file_vector, svg_file], check=True)
    print(f"Converted {svg_file} to {pdf_file_vector} using Inkscape.")
except (subprocess.CalledProcessError, FileNotFoundError):
    print("Inkscape not found. Skipping SVG to PDF conversion.")
    print("Please install Inkscape to use this method.")
# --- Step 3: Embed the vector PDF into a report PDF (using ReportLab) ---
# This is similar to Method 2, but we embed the vector PDF instead of a PNG.
if os.path.exists(pdf_file_vector):
    print("Creating final report PDF with embedded vector graphic...")
    from reportlab.lib.pagesizes import letter
    from reportlab.platypus import SimpleDocTemplate, Paragraph, KeepInFrame
    from reportlab.lib.styles import getSampleStyleSheet
    doc = SimpleDocTemplate("report_with_vector.pdf", pagesize=letter)
    styles = getSampleStyleSheet()
    Story = []
    p_title = Paragraph("<b>High-Quality Vector Report</b>", styles['h1'])
    Story.append(p_title)
    p_text = Paragraph("This report contains a 3D plot embedded as a **vector graphic**. "
                       "It can be scaled to any size without losing quality.", styles['Normal'])
    Story.append(p_text)
    # Use KeepInFrame to handle the PDF page size correctly
    vector_pdf = Image(pdf_file_vector, width=400, height=300, kind='vector')
    Story.append(KeepInFrame(400, 300, [vector_pdf]))
    doc.build(Story)
    print("Saved report_with_vector.pdf")

Pros:

  • Scalable Vector Graphics: The plot will be perfectly sharp at any zoom level or print size.
  • Highest possible quality for publications.

Cons:

  • Complex setup: Requires installing Inkscape (or similar tools like svg2pdf).
  • Mayavi's SVG export is not perfect and might not support all features or look identical to the on-screen render.

Method 4: Interactive Embedding in Jupyter

If your "PDF" is actually a Jupyter Notebook exported to PDF, you can embed interactive Mayavi plots. When the notebook is viewed in a browser (like JupyterLab), the plot is fully interactive. When exported to PDF, it becomes a static image, but the interactivity is preserved in the .ipynb file.

Example in a Jupyter Notebook Cell:

# This code must be run in a Jupyter Notebook or similar environment
import numpy as np
from mayavi import mlab
x, y = np.mgrid[-3:3:100j, -3:3:100j]
z = np.sin(x**2 + y**2) / (x**2 + y**2)
# mlab in a notebook automatically creates an interactive widget
mlab.surf(z, warp_scale='auto')
mlab.show() # Not always needed in notebooks, but good practice

How to get it into a PDF:

  1. Run the code in your Jupyter Notebook.
  2. Use the "Print" function in your browser (Ctrl+P / Cmd+P) and save as "PDF".
  3. Alternatively, use nbconvert to convert the .ipynb file to a PDF: jupyter nbconvert --to pdf my_notebook.ipynb.

Pros:

  • Provides interactive exploration within the notebook environment.
  • Excellent for sharing results with colleagues for them to explore.

Cons:

  • The interactivity is lost when exported to PDF. It becomes a static screenshot.
  • The final PDF is not a self-contained vector graphic.

Recommendation

  • For quick reports and presentations, use Method 1 (Matplotlib Backend) or Method 2 (Image Embed). They are the most practical.
  • For scientific publications or high-quality reports where image clarity is paramount, use Method 3 (E-Links / Vector Graphics). The extra effort is worth it for the final quality.
  • For interactive exploration and sharing workflows, use Method 4 (Jupyter Notebook).
分享:
扫描分享到社交APP
上一篇
下一篇