# How to turn a plot into pixels?

**URL:** https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061
**Category:** General Usage
**Created:** [March 19, 2019, 4:37pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061 "2019-03-19T16:37:45Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [March 19, 2019, 4:37pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/1 "2019-03-19T16:37:45Z")

</div>

Is there a fast way to turn a plot (from either Plots.jl or Makie) into an array of pixel values? Basically, I would like to be able to draw a few lines, and then turn that drawing into an `Array` of `UInt8` or similar, that I can use for further calculations.

(I could get the data that I need by saving a .png, then loading the image, but I need to do this hundreds of millions of times, so speed matters.)

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [March 19, 2019, 4:49pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/2 "2019-03-19T16:49:27Z")

</div>

Right away, `GLMakie.scene2image(scene)` should give you what you want.  
But that’s not super fast - even faster would be:

```julia
screen = display(your_scene)
image = colorbuffer(screen)

```

If you tell a bit about your use case, there might be even faster ways 😉

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [March 19, 2019, 7:28pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/3 "2019-03-19T19:28:13Z")

</div>

Thanks. This seems to be exactly what I was looking for.

My use case is generating a “movie” (time series of images) from a stochastic model. The movie is then used as training input for a kind of neural network. If there were a way to create movie frames in parallel on the GPU, that would be ideal, as the training takes place there.

---

<div class="post-metadata">

### Author: ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)
#### Post date: [March 19, 2019, 7:29pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/4 "2019-03-19T19:29:04Z")

</div>

If all you want to do is draw lines (or other primitive shapes), and you don’t need any fancy plotting functionality, you can probably save a ton of time by implementing your own line drawer onto an UInt8 matrix. It’s not terribly difficult, and there’s plenty of examples online you can use as a starting point.

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [March 19, 2019, 7:32pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/5 "2019-03-19T19:32:06Z")

</div>

Yes. This is exactly what I have been doing so far. But I think I will be using increasingly complex shapes, and I’d rather spend my time and energy on the neural network model than writing a new graphics library from scratch…

---

<div class="post-metadata">

### Author: ![affans](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/affans/32/11911_2.png) [@affans](https://discourse.julialang.org/u/affans)
#### Post date: [March 19, 2019, 9:46pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/6 "2019-03-19T21:46:24Z")

</div>

Can you point to an example. I am not sure what to google for exactly. I have the same problem that I’d like to create a movie of an agent-based model evolving through time.

---

<div class="post-metadata">

### Author: ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)
#### Post date: [March 19, 2019, 10:30pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/7 "2019-03-19T22:30:29Z")

</div>

Sure. For lines, a simple and efficient algorithm is [Bresenham’s](https://en.wikipedia.org/wiki/Bresenham%27s_line_algorithm). There’s pseudo code on that page, and you can find thousands of implementations online if you google for “Bresenham”, which can be trivially ported to Julia, or probably you can find Julia implementations already written. Here’s an example:

```julia
function line!(A, x0, y0, x1, y1)
    dx = abs(x1 - x0)
    sx = x0 < x1 ? 1 : -1
    dy = -abs(y1 - y0)
    sy = y0 < y1 ? 1 : -1
    err = dx + dy

    while true
        A[y0, x0] = 1
        x0 == x1 && y0 == y1 && break
        e2 = 2 * err
        e2 >= dy && (err += dy; x0 += sx)
        e2 <= dx && (err += dx; y0 += sy)
    end
end

```

Usage:

```julia
julia> A = zeros(UInt8, 8, 8);

julia> line!(A, 2, 2, 7, 6);

julia> @. Char(A*56)+32
8×8 Array{Char,2}:
 ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
 ' ' 'X' ' ' ' ' ' ' ' ' ' ' ' '
 ' ' ' ' 'X' ' ' ' ' ' ' ' ' ' '
 ' ' ' ' ' ' 'X' 'X' ' ' ' ' ' '
 ' ' ' ' ' ' ' ' ' ' 'X' ' ' ' '
 ' ' ' ' ' ' ' ' ' ' ' ' 'X' ' '
 ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
 ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '

```

Of course implementing one’s own drawing code sounds like a terrible idea and a last resort, but presumably it can be made significantly faster than going through an existing plotting library and rasterizing the result at the end.

---

<div class="post-metadata">

### Author: ![magister-ludi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/magister-ludi/32/4003_2.png) [@magister-ludi](https://discourse.julialang.org/u/magister-ludi)
#### Post date: [March 19, 2019, 10:48pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/8 "2019-03-19T22:48:49Z")

</div>

It will depend a bit on the quality you want. The classic anti-aliasing algorithm is the “Bresenham algorithm”. A search for that should get you somewhere.

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [March 20, 2019, 9:59am UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/9 "2019-03-20T09:59:11Z")

</div>

> [@bennedich](#):
>
> Of course implementing one’s own drawing code sounds like a terrible idea and a last resort, but presumably it can be made significantly faster than going through an existing plotting library and rasterizing the result at the end.

I doubt that you’ll be faster than Makie in the end, especially for many drawing operations!

---

<div class="post-metadata">

### Author: ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)
#### Post date: [March 20, 2019, 11:22am UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/10 "2019-03-20T11:22:56Z")

</div>

If I understood the original post correctly, he wanted to draw a few lines, then rasterize the result to an UInt8 matrix, and repeat that whole process hundreds of millions of times. I haven’t benchmarked it, but I would suspect that this can be done considerably faster on pure CPU writing straight to the UInt8 matrix (~1 μs per line), than on GPU and transfer the results to system memory for each frame. Don’t you think?

If he wants to draw more complex shapes, and/or more than a few lines, that’s a different situation, but then it probably needs to be looked at in a broader perspective, not just what’s the fastest way to rasterize an image regardless of plotting library, but the fastest overall to draw the desired shapes and get the resulting image.

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [March 20, 2019, 12:13pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/11 "2019-03-20T12:13:05Z")

</div>

I guess it was a bit ballsy, considering how little information there are 😉  
Really depends on the size of the matrix and the number of shapes!  
Transfer costs for a 960x540 color targets is ~70μs, which will be the constant overhead you’ll need to pay - but the drawing should be much faster than on the CPU!

But you could actually directly render to a uint8 rendertarget and make a cuda buffer out of it, which you could directly use with CuArrays + Flux 😉 That should be quite unbeatable!

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [March 20, 2019, 12:48pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/12 "2019-03-20T12:48:34Z")

</div>

> [@sdanisch](#):
>
> But you could actually directly render to a uint8 rendertarget and make a cuda buffer out of it, which you could directly use with CuArrays + Flux 😉 That should be quite unbeatable!

Yes, like I said, I will do further processing on the GPU in any case, so for me it would be an advantage that the drawing happens there, if I can then get the image directly as a `CuArray`.

Is there a way to do that?

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [March 20, 2019, 1:45pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/13 "2019-03-20T13:45:33Z")

</div>

It’s not super straight forward… I tried it a couple of times and it was always a hassle to get this right.  
You can take a look at the last message in:

> **[Passing source pointer from OpenGL texture to cuda kernel?](https://forums.developer.nvidia.com/t/passing-source-pointer-from-opengl-texture-to-cuda-kernel/54281)**
>
> Greetings All, I have a question regarding performance when interop between cuda and opengl is involved, and secondarily I was hoping to get a clarification on how to read/write to an opengl texture from a cuda thread. What i have working...

```julia
using Makie, GLMakie

scene = scatter(rand(5))

screen = display(scene)
color_texture = screen.framebuffer.color;

```

This gives you the texture which should hold all the right handles 😉

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [March 20, 2019, 2:25pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/14 "2019-03-20T14:25:12Z")

</div>

Thanks for the info! Very likely `AbstractPlotting.colorbuffer(screen)` will already be fast enough in relation to the rest of my code, so if it’s too much of a hassle to avoid the return trip to CPU memory, then I’ll just let it be.

---

<div class="post-metadata">

### Author: ![sdanisch](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/sdanisch/32/1406_2.png) [@sdanisch](https://discourse.julialang.org/u/sdanisch)
#### Post date: [March 20, 2019, 2:33pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/15 "2019-03-20T14:33:01Z")

</div>

Btw, if you use colorbuffer, you can also disable the renderloop to do a bit less duplicate work:

```julia
GLMakie.opengl_renderloop[] = (screen) -> nothing

```

---

<div class="post-metadata">

### Author: ![bjarthur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bjarthur/32/9638_2.png) [@bjarthur](https://discourse.julialang.org/u/bjarthur)
#### Post date: [February 10, 2020, 1:38pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/16 "2020-02-10T13:38:51Z")

</div>

> **[GitHub - JuliaImages/ImageDraw.jl: Drawing Package for JuliaImages](https://github.com/JuliaImages/ImageDraw.jl)**
>
> Drawing Package for JuliaImages. Contribute to JuliaImages/ImageDraw.jl development by creating an account on GitHub.

---

<div class="post-metadata">

### Author: ![bjarthur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bjarthur/32/9638_2.png) [@bjarthur](https://discourse.julialang.org/u/bjarthur)
#### Post date: [February 10, 2020, 1:46pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/17 "2020-02-10T13:46:07Z")

</div>

you could also PyCall.jl out to [Module: draw — skimage v0.20.0.dev0 docs](https://scikit-image.org/docs/dev/api/skimage.draw.html#skimage.draw.line_aa) if ImagesDraw.jl is not enough.

---

<div class="post-metadata">

### Author: ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)
#### Post date: [February 10, 2020, 2:00pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/18 "2020-02-10T14:00:29Z")

</div>

ImageDraw looks like it might be quite useful. Is there documentation for it anywhere?

---

<div class="post-metadata">

### Author: ![bjarthur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bjarthur/32/9638_2.png) [@bjarthur](https://discourse.julialang.org/u/bjarthur)
#### Post date: [February 18, 2020, 3:22pm UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/19 "2020-02-18T15:22:00Z")

</div>

use the tests Luke

---

<div class="post-metadata">

### Author: ![AbelHo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/abelho/32/47383_2.png) [@AbelHo](https://discourse.julialang.org/u/AbelHo)
#### Post date: [March 8, 2023, 9:15am UTC](https://discourse.julialang.org/t/how-to-turn-a-plot-into-pixels/22061/20 "2023-03-08T09:15:27Z")

</div>

Hi all,  
I am looking for a way to turn plots(Plots.jl) into image pixel color value 2D array too. Then using each image to generate each video frame (as described in [Writing Videos · VideoIO.jl](https://juliaio.github.io/VideoIO.jl/stable/writing/#Iterative-Encoding) )

Any updates on a solution for this?  
I can use png() to get iobuffer then convert that(using Images.jl) back to an image array, but that’s two extra steps.

The Makie method as suggested by @sdanisch works well. But I am facing memory leak([Makie memory leak? · Issue #795 · MakieOrg/Makie.jl · GitHub](https://github.com/MakieOrg/Makie.jl/issues/795)) on each plot and julia crashes before I can finish generating all my frames. I am also thinking Plots.jl might be more lightweight compared to using GLMakie.

Welcome for any suggestions! 🙂
