M
Morne
Guest
GM Version: GM v2.1.3.273 Runtime v2.1.3.189
Target Platform: ALL for general tutorial
Download: N/A, until feature complete or if there is a big need
Links: N/A
Difficulty: Medium, GML knowledge required to modify.
Summary:
Plot basic single array of values on a Y-X-plot to a surface object. Place it anywhere and with custom Height and Width for plot surface. Plot (graph) will autoscale the Y & X axis based on axis scale to stretch it to surface size. Very basic implementation to get you started. Will demo a sigmoid() function {also useful when building neural nets}. Example function call in GM DRAW event (if inputs defined):
Tutorial:
Here is example result (on black background):
First you will need an array of X values and calculate some equation Y values, I've provided you with the sigmoid() function, see script below:
Extra:
If you rather want to plot the derivative of sigmoid, you can have this one below:
I will use sigmoid(n) for to replicate the plot graph above. But you can pass any data in an X & Y array to the draw_plot(...) function, as long as they are of equal length. The purpose of this was to plot equation results, which will always yield the same number of Y-values for X-values as defined in the plot space x-axis and y-axis. Please be careful not to get confused with the game maker x,y pixel coordinates. This function will translate automatically the Y, X values of the data to the x,y pixel coordinates on your surface.
The method I used was to use a custom object 'objPlot' so I can create my graph plot anywhere. This function draw_plot() function will thus be called in the 'objPlot' draw event, with some other code in its create event to initialise the plot surface variables. This also will enable you to easily add plot draw controls ingame or should I say in-app. I will not cover the ingame controls in this tutorial and leave it up to you for an excercise.
1. So if you have not created the sigmoid() function yet, please create a script and copy the sigmoid() script above into it and save it.
2. Now create a new object called 'objPlot' or whatever you want. This will when created or placed in a room draw the plot surface with this object x,y as its top left corner. (see variables surfX, surfY in objPlot create event below)
3. Add a CREATE EVENT and add the code below: {code blocks are commented and will not be explained in detail}
4. Add an Alarm[0] EVENT, add code below:
5. Add a DRAW EVENT, add code below:
6. Place 'objPlot' in room (preferably just left of center and top area of room), SAVE game.
7. Run game (press F5)!
8. Extra:
If you want to test plot axis scaling ingame then add a Key Press LEFT EVENT with
and also add EVENT: Key Press - RIGHT with
Then SAVE, and RUN (F5) again.
Feel free to comment, ask questions or suggest improvements. I just wanted to share this feature since it is not part of out of the box GMS functionality and shows how to use surfaces. It is very basic and currently can only draw one graph, but you can easily draw additional ones while the surface is in target in the draw_plot() function.
Target Platform: ALL for general tutorial
Download: N/A, until feature complete or if there is a big need
Links: N/A
Difficulty: Medium, GML knowledge required to modify.
Summary:
Plot basic single array of values on a Y-X-plot to a surface object. Place it anywhere and with custom Height and Width for plot surface. Plot (graph) will autoscale the Y & X axis based on axis scale to stretch it to surface size. Very basic implementation to get you started. Will demo a sigmoid() function {also useful when building neural nets}. Example function call in GM DRAW event (if inputs defined):
Code:
draw_plot(surfX,surfY,surfW,surfH, Xvals,Yvals, minX,maxX,minY,maxY,axisTic);
Here is example result (on black background):
First you will need an array of X values and calculate some equation Y values, I've provided you with the sigmoid() function, see script below:
Code:
/// @function sigmoid(n)
/// @description Returns 'x' conversion to 0-1 value clipping, formula '1/(1-exp(-n))' for an 'n' range of (-5.30 to +5.30) useful for Neural Nets input scaling or normalisation
/// @arg {real} n where n is any typical equation X value
var n = argument0;
return 1/(1+exp(-n))
If you rather want to plot the derivative of sigmoid, you can have this one below:
Code:
/// @function sigmoid_derivative(n)
/// @description Returns the Derivative or phi of equation sigmoid(n)
/// @arg {real} n where n is any typical equation X value
var n = argument0;
return sigmoid(n)*(1-sigmoid(n))
The method I used was to use a custom object 'objPlot' so I can create my graph plot anywhere. This function draw_plot() function will thus be called in the 'objPlot' draw event, with some other code in its create event to initialise the plot surface variables. This also will enable you to easily add plot draw controls ingame or should I say in-app. I will not cover the ingame controls in this tutorial and leave it up to you for an excercise.
1. So if you have not created the sigmoid() function yet, please create a script and copy the sigmoid() script above into it and save it.
2. Now create a new object called 'objPlot' or whatever you want. This will when created or placed in a room draw the plot surface with this object x,y as its top left corner. (see variables surfX, surfY in objPlot create event below)
3. Add a CREATE EVENT and add the code below: {code blocks are commented and will not be explained in detail}
Code:
/// @description Insert description here
// You can write your code in this editor
surfID = -1;
canUpdateSurface = true;
canClearSurface = false;
//Init (for function in draw event below)
//draw_plot(x,y,480,320,Xvals,Yvals,-5,6,-5,10,1);
//draw_plot(surfX,surfY,surfW,surfH, Xvals,Yvals, minX,maxX,minY,maxY,axisTic);
surfX = x;
surfY = y;
surfW = 480;
surfH = 320;
minX = -5;
minY = -2;
maxX = 5;
maxY = 2;
axisTic = 1;
//this enable to add keyboard/button dynamic control to plot
//axisTicIncrement = 0.1;
/* TEST DATA Array[]*/
Xvals = [-6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6];
//Evaluate Yvalues and create array for sigmoid(Xvals)
lenA = array_length_1d(Xvals);
for (var i=lenA-1; i>-1; i--;) {
Yvals[i] = sigmoid(Xvals[i]); //custom equation
}
Code:
/// @description canUpdateSurface = true
canUpdateSurface = true;
Code:
/// @description Insert description here
// You can write your code in this editor
//draw_self();
//Debug: Draw values in list left of Plot (not on surface)
draw_set_color(c_white);
for (var i=0; i<array_length_1d(Yvals); i++;) {
draw_text(x-128,y+i*16,"(Xval,Yval)=("+string(Xvals[i])+","+string(Yvals[i])+")");
}
//Draw actual plot
//draw_plot(x,y,480,320,Xvals,Yvals,-5,6,-5,10,1);
draw_plot(surfX,surfY,surfW,surfH, Xvals,Yvals, minX,maxX,minY,maxY,axisTic);
7. Run game (press F5)!
8. Extra:
If you want to test plot axis scaling ingame then add a Key Press LEFT EVENT with
Code:
/// @description decrease minX
minX -= axisTic; //axisTicIncrement;
canClearSurface = true;
Code:
/// @description increase maxX
maxX += axisTic; //axisTicIncrement;
canClearSurface = true;
Feel free to comment, ask questions or suggest improvements. I just wanted to share this feature since it is not part of out of the box GMS functionality and shows how to use surfaces. It is very basic and currently can only draw one graph, but you can easily draw additional ones while the surface is in target in the draw_plot() function.