GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — reorganized Figure export stuff by kushalkolar · Pull Request #710 · fastplotlib/fastplotlib

Conversation

@kushalkolar

@kushalkolar kushalkolar commented Jan 26, 2025 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

Adds a new method Figure.export_numpy().

Removes the FigureRecorder because that thing is hard to test and IMO kinda out of scope and a mess. Instead once we expose the "onedemand" render mode in fastplotlib which now exists in rendercanvs we can provide examples using Figure.export_numpy() to export frames as numpy arrays that can then be written to disk using the user's favorite video writer, such as opencv.

@apasarkar @FlynnOConnell

These examples currently don't work because we don't have "ondemand" mode in fastplotlib yet, documenting here for a future PR:

"""
ImageWidget export images or video
==================================

This example is meant to be run in an interactive shell. To run in a script use the offscreen canvas.

imageio is required to export to images.

This example uses opencv to export to a video but you don't have to use opencv, you
can use any other video writer that can write numpy arrays to video frames.
"""

# test_example = true
# sphinx_gallery_pygfx_docs = 'code'

# %%
import fastplotlib as fpl
import imageio.v3 as iio
import cv2


movie = iio.imread("imageio:cockatoo.mp4")

iw = fpl.ImageWidget(
    movie,
    rgb=[True],
    figure_kwargs={"size": (700, 560), "canvas": "offscreen"}  # for offscreen rendering provide "canvas": "offscreen"
)

# show image widget
iw.show()

# %%

# wait for image widget to display

# export a snapshot of the figure as it is currently displayed
iw.figure.export("./image.png")

# obtain a numpy array
frame = iw.figure.export_numpy(rgb=True)

# %%
# create a video writer
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
writer = cv2.VideoWriter(
    "./iw_video.mp4",
    fourcc,
    20.0,
    (frame.shape[1], frame.shape[0]),
)

# write a video file of the first 100 frames
for i in range(100):
    frame = iw.figure.export_numpy(rgb=True)
    writer.write(frame)
    iw.current_index = {"t": i}

writer.release()
"""
Figure export images or video
=============================

This example is meant to be run in an interactive shell. To run in a script use the offscreen canvas.

imageio is required to export to images.

This example uses opencv to export to a video but you don't have to use opencv, you
can use any other video writer that can write numpy arrays to video frames.
"""

# test_example = false
# sphinx_gallery_pygfx_docs = 'code'

# %%
import fastplotlib as fpl
import numpy as np
import cv2

# create a random distribution of 10,000 xyz coordinates
n_points = 10_000

# dimensions always have to be [n_points, xyz]
dims = (n_points, 3)

clouds_offset = 15

# create some random clouds
normal = np.random.normal(size=dims, scale=5)
# stack the data into a single array
cloud = np.vstack(
    [
        normal - clouds_offset,
        normal,
        normal + clouds_offset,
    ]
)

# color each of them separately
colors = ["yellow"] * n_points + ["cyan"] * n_points + ["magenta"] * n_points

# create plot
figure = fpl.Figure(
    size=(700, 560),
    canvas="offscreen"  # for offscreen rendering, ex. in a script
)
subplot_scatter = figure[0, 0]
# use an alpha value since this will be a lot of points
scatter_graphic = subplot_scatter.add_scatter(data=cloud, sizes=3, colors=colors, alpha=0.6)


def update():
    # move every point by a small amount
    deltas = np.random.normal(size=scatter_graphic.data.value.shape, loc=0, scale=0.05)
    scatter_graphic.data = scatter_graphic.data.value + deltas


figure.show()

# %%

# wait for figure to display

# export a snapshot of the figure as it is currently displayed
figure.export("./image.png")

# obtain a numpy array
frame = figure.export_numpy(rgb=True)

# %%
# create a video writer
fourcc = cv2.VideoWriter_fourcc(*'XVID')
writer = cv2.VideoWriter(
    "./scatter_video.avi",
    fourcc,
    50.0,
    (frame.shape[1], frame.shape[0]),
)

# write a video file with 500 frames
for i in range(500):
    frame = figure.export_numpy(rgb=True)
    writer.write(frame)
    # update the graphic
    update()

writer.release()

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@kushalkolar
reorganized Figure export stuff
575a9f5
@kushalkolar
kushalkolar requested a review from clewis7 as a code owner January 26, 2025 08:45
@github-actions

github-actions Bot commented Jan 26, 2025

Copy link
Copy Markdown

📚 Docs preview built and uploaded! https://www.fastplotlib.org/ver/export-numpy

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

clewis7
clewis7 approved these changes Jan 26, 2025
View reviewed changes
@clewis7

clewis7 commented Jan 26, 2025

Copy link
Copy Markdown
Member

@kushalkolar is this gtg?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@kushalkolar

kushalkolar commented Jan 26, 2025

Copy link
Copy Markdown
Member Author

Yup ready for review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@clewis7
clewis7 merged commit d4af1a9 into main Jan 26, 2025
@clewis7
clewis7 deleted the export-numpy branch January 26, 2025 20:25
@kushalkolar kushalkolar mentioned this pull request Jan 30, 2025
figure.export() usage outside of a notebook #714
Open
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@clewis7 clewis7 clewis7 approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@kushalkolar @clewis7
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.