/build/arrayfire/src/arrayfire-full-3.6.1/docs/pages/forge_visualization.md
Go to the documentation of this file.
1 Visualizing af::array with Forge {#forge_visualization}
2 ===================
3 
4 Arrayfire as a library aims to provide a robust and easy to use platform for
5 high-performance, parallel and GPU computing.
6 
7 [TOC]
8 
9 The goal of [Forge](https://github.com/arrayfire/forge), an OpenGL visualization
10 library, is to provide equally robust visualizations that are interoperable
11 between Arrayfire data-structures and an OpenGL context.
12 
13 Arrayfire provides wrapper functions that are designed to be a simple interface
14 to visualize af::arrays. These functions perform various interop tasks. One in
15 particular is that instead of wasting time copying and reformatting data from
16 the GPU to the host and back to the GPU, we can draw directly from GPU-data to
17 GPU-framebuffers! This saves 2 memory copies.
18 
19 Let's see exactly what visuals we can illuminate with forge and how Arrayfire
20 anneals the data between the two libraries.
21 
22 # Setup {#setup}
23 Before we can call Forge functions, we need to set up the related "canvas" classes.
24 Forge functions are tied to the af::Window class. First let's create a window:
25 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
26 const static int width = 512, height = 512;
27 af::Window window(width, height, "2D plot example title");
28 
29 do{
30 
31 //drawing functions here
32 
33 } while( !window.close() );
34 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
35 
36 We also added a drawing loop, so now we can use Forge's drawing functions to
37 draw to the window.
38 The drawing functions present in Forge are listed below.
39 
40 # Rendering Functions {#render_func}
41 
42 Documentation for rendering functions can be found [here](\ref gfx_func_draw).
43 
44 ## Image {#image}
45 The af::Window::image() function can be used to plot grayscale or color images.
46 To plot a grayscale image a 2d array should be passed into the function.
47 Let's see this on a static noise example:
48 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
49 array img = constant(0, width, height); //make a black image
50 array random = randu(width, height); //make random [0,1] distribution
51 img(random > 0.5) = 1; //set all pixels where distribution > 0.5 to white
52 
53 window.image(img);
54 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55 <img src="gfx_docs_images/noise.png" alt="Forge image plot of noise" width="20%" />
56 Tweaking the previous example by giving our image a depth of 3 for the RGB values
57 allows us to generate colorful noise:
58 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
59 array img = 255 * randu(width, height, 3); //make random [0, 255] distribution
60 window.image( img.as(u8) );
61 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
62 <img src="gfx_docs_images/color_noise.png" alt="Forge image plot of color noise" width="20%" />
63 Note that Forge automatically handles any af::array type passed from Arrayfire.
64 In the first example we passed in an image of floats in the range [0, 1].
65 In the last example we cast our array to an unsigned byte array with the range
66 [0, 255]. The type-handling properties are consistent for all Forge drawing functions.
67 
68 ## Plot {#plot}
69 The af::Window::plot() function visualizes an array as a 2d-line plot. Let's see
70 a simple example:
71 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
72 array X = seq(-af::Pi, af::Pi, 0.01);
73 array Y = sin(X);
74 window.plot(X, Y);
75 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
76 
77 <img src="gfx_docs_images/sin_plot.png" alt="Forge 2d line plot of sin() function" width="30%" />
78 The plot function has the signature:
79 
80 > **void plot( const array &X, const array &Y, const char * const title = NULL );**
81 
82 Both the x and y coordinates of the points are required to plot. This allows for
83 non-uniform, or parametric plots:
84 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
85 array t = seq(0, 100, 0.01);
86 array X = sin(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));
87 array Y = cos(t) * (exp(cos(t)) - 2 * cos(4 * t) - pow(sin(t / 12), 5));
88 window.plot(X, Y);
89 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
90 
91 <img src="gfx_docs_images/butterfly_plot.png" alt="Forge 2d line plot of butterfly function" width="30%" />
92 
93 ## Plot3 {#plot3}
94 The af::Window::plot3() function will plot a curve in 3d-space.
95 Its signature is:
96 > **void plot3 (const array &in, const char * title = NULL);**
97 The input array expects xyz-triplets in sequential order. The points can be in a
98 flattened one dimensional (*3n x 1*) array, or in one of the (*3 x n*), (*n x 3*) matrix forms.
99 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
100 array Z = seq(0.1f, 10.f, 0.01);
101 array Y = sin(10 * Z) / Z;
102 array X = cos(10 * Z) / Z;
103 
104 array Pts = join(1, X, Y, Z);
105 //Pts can be passed in as a matrix in the from n x 3, 3 x n
106 //or in the flattened xyz-triplet array with size 3n x 1
107 window.plot3(Pts);
108 //both of the following are equally valid
109 //window.plot3(transpose(Pts));
110 //window.plot3(flat(Pts));
111 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
112 <img src="gfx_docs_images/spiral_plot3.png" alt="Forge 3d line plot" width="40%" />
113 
114 ## Histogram {#histogram}
115 The af::Window::hist() function renders an input array as a histogram.
116 In our example, the input array will be created with Arrayfire's histogram()
117 function, which actually counts and bins each sample. The output from histogram()
118 can directly be fed into the af::Window::hist() rendering function.
119 
120 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
121 const int BINS = 128; SAMPLES = 9162;
122 array norm = randn(SAMPLES);
123 array hist_arr = histogram(norm, BINS);
124 
125 win.hist(hist_arr, 0, BINS);
126 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
127 In addition to the histogram array with the number of samples in each bin, the
128 af::Window::hist() function takes two additional parameters -- the minimum and
129 maximum values of all datapoints in the histogram array. This effectively sets
130 the range of the binned data. The full signature of af::Window::hist() is:
131 > **void hist(const array & X, const double minval, const double maxval, const char * const title = NULL);**
132 <img src="gfx_docs_images/norm_histogram.png" alt="Forge 3d scatter plot" width="40%" />
133 
134 
135 ## Surface {#surface}
136 The af::Window::surface() function will plot af::arrays as a 3d surface.
137 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
138 array Z = randu(21, 21);
139 window.surface(Z, "Random Surface"); //equal to next function call
140 //window.surface( seq(-1, 1, 0.1), seq(-1, 1, 0.1), Z, "Random Surface");
141 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
142 <img src="gfx_docs_images/rand_surface.png" alt="Forge random surface plot" width="30%" />
143 There are two overloads for the af::Window::surface() function:
144 > **void surface (const array & S, const char * const title )**
145 > // Accepts a 2d matrix with the z values of the surface
146 
147 > **void surface (const array &xVals, const array &yVals, const array &S, const char * const title)**
148 > // accepts additional vectors that define the x,y coordinates for the surface points.
149 
150 The second overload has two options for the x, y coordinate vectors. Assuming a surface grid of size **m x n**:
151  1. Short vectors defining the spacing along each axis. Vectors will have sizes **m x 1** and **n x 1**.
152  2. Vectors containing the coordinates of each and every point.
153  Each of the vectors will have length **mn x 1**.
154  This can be used for completely non-uniform or parametric surfaces.
155 
156 # Conclusion {#conclusion}
157 There is a fairly comprehensive collection of methods to visualize data in Arrayfire.
158 Thanks to the high-performance gpu plotting library Forge, the provided Arrayfire
159 functions not only make visualizations as simple as possible, but keep them as
160 robust as the rest of the Arrayfire library.