Recap of the hierarchy of each plot element: Difference between revisions

From Octave
Jump to navigation Jump to search
No edit summary
(Move up to Category:Tutorials.)
 
(11 intermediate revisions by 8 users not shown)
Line 1: Line 1:
First of all, Octave aims at being compatible with Matlab (TM) as much as possible, so the graphics part is very similar too to Matlab. In Octave the first choice to make is the {{Codeline|graphics_toolkit()}}. Standard is the 'gnuplot' toolkit using the [http://www.gnuplot.info Gnuplot] software package . The second choice is 'fltk' [http://www.fltk.org fltk]. You might want to try to test both of them for your plotting aims to see which solves your problem.
Octave aims at being compatible with Matlab as much as possible, so the graphics part is very similar too to Matlab. In Octave the first choice to make is the {{Codeline|graphics_toolkit ()}}. There are currently (sep. 2015) 3 available plotting back-ends (graphics toolkits):
* 'qt' (the default since Octave 4.0) and 'fltk' both rely on the same OpenGl based rendering engine.
* 'gnuplot' toolkit uses the [http://www.gnuplot.info Gnuplot] software package.
You might want to try to test all of them for your plotting aims to see which solves your problem. Some graphics problems (wrong font, missing sub/superscript, wrong line style, etc) relate specifically to one graphics_toolkit in Octave, so you might want to try the other one. In general OpenGl based toolkits are much faster than 'gnuplot'. On the other hand, as 'gnuplot' is more mature, the printed outputs (in raster or vector formats) are much more good looking and generally suitable for publication.  


After the choice of the {{Codeline|graphics_toolkit('gnuplot')}} or {{Codeline|graphics_toolkit('fltk')}}, there is the following hierarchy to address when make/adapting your plot:
A plot is composed of various objects (figure window, axes, lines, images ...) which all feature a set of useful properties as we will see below. The graphics objects are organized according to the following hierarchy:


* root  (any hierarchy needs to start somewhere)
* root: the base object. Mainly features properties related to screen description.  
* gcf() (the handle to your figure: one for every figure)
* figure: represents a figure windows. Figures are children of the root object.
* gca() (the handle to the axes inside a particular figure (several if you have subplots)  
* axes: represents a set of x, y (,z) axes. Axes are children of figure objects.
* p=plot(x,y) (p is the handle (inside the current axes handle) to the data, data symbols, data line thickness, etc)
* line: represents curves. Lines are children of axes (or hggroup, see below) objects. This is typically what is used by the basic {{Codeline|plot (...)}} function to draw curves.
* patch: represents unstructured surface. Patches are children of axes (or hggroup, see below) objects. Patches are used when one wants to draw 2 dimensional unstructured surfaces and have fine control over their color.
* image: represents a  2D set of pixels. Images are children of axes (or hggroup, see below) objects.
* surface: represents structured surfaces. Surfaces are children of axes (or hggroup, see below) objects. Structured meshes made of quads are generally represented using surfaces.
* text: represents a text label. Texts are children of axes (or hggroup, see below) objects.
* hggroup: convenience object to group graphics objects. Among others useful properties, the 'visible' property of and hggroup acts on the visibility of all its children objects (line, text, ...)


Let's do an example:
The law level functions that are used to create the above objects have the same name as the object. They all return a unique handle (a variable of type double) that can be further used to change the object properties using {{Codeline|set (h, POPERTY, VALUE)}}.
 
 
In general one would use higher level function such as in the example below::
{{Code||<syntaxhighlight lang="octave" style="font-size:13px">
graphics_toolkit ("qt");
x = 0:0.1:3;
y = sin (x);
p = plot (x, y, "b");
</syntaxhighlight>}}


graphics_toolkit('gnuplot');
x=0:0.1:3;
y=sin(x);
p=plot(x,y,'b');


This should get you a plot of a part of a sine wave. Octave has used all standard properties like line widths, fonts, etc, except for the line color which was forced to be blue (via the {{Codeline|'b'}}).
This should get you a plot of a part of a sine wave. Octave has used all standard properties like line widths, fonts, etc, except for the line color which was forced to be blue (via the {{Codeline|'b'}}).
Line 19: Line 32:
Before going into the hierarchy and how to change things, let's make things more complicated:
Before going into the hierarchy and how to change things, let's make things more complicated:


  graphics_toolkit('gnuplot');
  graphics_toolkit ("gnuplot");
  figure(1)
  figure (1)
  x=0:0.1:3;
  x = 0:0.1:3;
  y=sin(x);
  y = sin (x);
  p=plot(x,y,'b');
  p = plot (x, y, "b");
  figure(2)
  figure (2)
  subplot(2,1,1);
  subplot (2, 1, 1);
  r=plot(x,y.^2,'og');
  r = plot (x, y.^2, "og");
  subplot(2,1,2);
  subplot (2, 1, 2);
  q=plot(x,x.^2,'k');
  q = plot (x, x.^2, "k");
 
* You now have 2 windows that popped up on your screen: figure1 and figure2.
* figure2 has 2 axes objects inside: a 'y=(sin(x))^2' and a 'y=x^2'
* the actual data and data-plot-properties are inside the handles {{Codeline|p}} and {{Codeline|r}}.


So let's say you want to change the line thickness of the data in the first figure:
* You now have 2 windows that popped up on your screen: figure 1 and figure 2. Their handle is the integer figure number (1 and 2 here)
* figure 2 has two axes objects inside. In order to have access to those axes properties one could have stored its handle, returned by the subplot function, e.g. {{Codeline|<nowiki>hax = subplot (2,1,1)</nowiki>}}
* the actual curves {{Codeline|<nowiki>y = sin (x) .^2</nowiki>}} and {{Codeline|<nowiki>y = x.^2</nowiki>}} are line objects that can be tuned using their repsective handles {{Codeline|p}} and {{Codeline|r}}.


  figure(1)
So let's say you want to change the line thickness of the curve in figure 1:
  set(p,'linewidth',3)
  figure (1)
  set (p, "linewidth", 3)


You can get the color of the two other plots by referring to their handles:
You can get the color of the two other plots by referring to their handles:
  get(q,'color')
  get (q, "color")
  get(r,'color')
  get (r, "color")
Which will give you the RGB code for black (0,0,0) and green (0,1,0).
Which will give you the RGB code for black (0,0,0) and green (0,1,0).


Have a look at all the things you can change with:
Have a look at all the properties of line objects:
  get(q)
  get (q)
 
Some of those properties are read-only, while others have a limited set of allowed values. You may also want to look at modifiable properties and their allowed values:
set (q)


And {{Codeline|set}} anything that is not to your taste to something else (for what's available see the [http://www.gnu.org/software/octave/doc/interpreter/ manual]).
And {{Codeline|set}} anything that is not to your taste to something else (for what's available see the [http://www.gnu.org/software/octave/doc/interpreter/ manual]).
  set(p,'marker','*')
  set (p, "marker", "*")


Adding {{Codeline|text()}} inside an {{Codeline|axes()}} object is done by
Adding {{Codeline|text()}} inside an {{Codeline|axes()}} object is done by
  text(2,0.8,'HERE');
  text (2, 0.8, "HERE");
... but it now inserted in figure1, which ''might NOT be want you anticipated''.
... but it now is inserted in figure 1, which ''might NOT be what you anticipated''.
   
   
The {{Codeline|text()}} command does ''not'' have the option to tell it in which figure or axes object to write the text.
All low and high level plotting functions draw by default on the 'currentfigure' in the 'currentaxes' for which the handles can be retrieved using:
Make sure you have moved current figure and axes ''before'' calling {{Codeline|text()}} to insert text:
hfig = gcf (); # returns a handle to the current figure
  figure(2)
hax = gca ();  # returns a handle to the current axes
  get(gcf(),'children') % which two axes objects are there inside figure(2)
 
  set(gcf(),'currentaxes',(get(gcf(),'children'))(2)) % chose the second one
In order to change the current figure/axes and draw in figure 2 you may either make them current using the the figure {{Codeline|figure (NFIG)}} function:  
  text(1.0,0.5,'THIS IS WHAT I WANTED')
  figure (2) # figure 2 is now the current, let's check
get (0, "currentfigure")
  haxes = get (gcf (),"children") # retrieve all axes handles
  set (gcf (), "currentaxes", haxes(2)) # set the second axes current
text (1.0, 0.5, "THIS IS WHAT I WANTED")
 
... or explicitly specify the parent object in which you would like to draw the text:
haxes = get (2, "children") # retrieve all axes handles
  text (1.0, 0.5, "THIS IS WHAT I WANTED", "parent", haxes (2))


text(1,0.5,"This is where I wanted my text");
[[Category:Tutorials]]

Latest revision as of 22:07, 13 June 2019

Octave aims at being compatible with Matlab as much as possible, so the graphics part is very similar too to Matlab. In Octave the first choice to make is the graphics_toolkit (). There are currently (sep. 2015) 3 available plotting back-ends (graphics toolkits):

  • 'qt' (the default since Octave 4.0) and 'fltk' both rely on the same OpenGl based rendering engine.
  • 'gnuplot' toolkit uses the Gnuplot software package.

You might want to try to test all of them for your plotting aims to see which solves your problem. Some graphics problems (wrong font, missing sub/superscript, wrong line style, etc) relate specifically to one graphics_toolkit in Octave, so you might want to try the other one. In general OpenGl based toolkits are much faster than 'gnuplot'. On the other hand, as 'gnuplot' is more mature, the printed outputs (in raster or vector formats) are much more good looking and generally suitable for publication.

A plot is composed of various objects (figure window, axes, lines, images ...) which all feature a set of useful properties as we will see below. The graphics objects are organized according to the following hierarchy:

  • root: the base object. Mainly features properties related to screen description.
  • figure: represents a figure windows. Figures are children of the root object.
  • axes: represents a set of x, y (,z) axes. Axes are children of figure objects.
  • line: represents curves. Lines are children of axes (or hggroup, see below) objects. This is typically what is used by the basic plot (...) function to draw curves.
  • patch: represents unstructured surface. Patches are children of axes (or hggroup, see below) objects. Patches are used when one wants to draw 2 dimensional unstructured surfaces and have fine control over their color.
  • image: represents a 2D set of pixels. Images are children of axes (or hggroup, see below) objects.
  • surface: represents structured surfaces. Surfaces are children of axes (or hggroup, see below) objects. Structured meshes made of quads are generally represented using surfaces.
  • text: represents a text label. Texts are children of axes (or hggroup, see below) objects.
  • hggroup: convenience object to group graphics objects. Among others useful properties, the 'visible' property of and hggroup acts on the visibility of all its children objects (line, text, ...)

The law level functions that are used to create the above objects have the same name as the object. They all return a unique handle (a variable of type double) that can be further used to change the object properties using set (h, POPERTY, VALUE).


In general one would use higher level function such as in the example below::

 graphics_toolkit ("qt");
 x = 0:0.1:3;
 y = sin (x);
 p = plot (x, y, "b");


This should get you a plot of a part of a sine wave. Octave has used all standard properties like line widths, fonts, etc, except for the line color which was forced to be blue (via the 'b').

Before going into the hierarchy and how to change things, let's make things more complicated:

graphics_toolkit ("gnuplot");
figure (1)
x = 0:0.1:3;
y = sin (x);
p = plot (x, y, "b");
figure (2)
subplot (2, 1, 1);
r = plot (x, y.^2, "og");
subplot (2, 1, 2);
q = plot (x, x.^2, "k");
  • You now have 2 windows that popped up on your screen: figure 1 and figure 2. Their handle is the integer figure number (1 and 2 here)
  • figure 2 has two axes objects inside. In order to have access to those axes properties one could have stored its handle, returned by the subplot function, e.g. hax = subplot (2,1,1)
  • the actual curves y = sin (x) .^2 and y = x.^2 are line objects that can be tuned using their repsective handles p and r.

So let's say you want to change the line thickness of the curve in figure 1:

figure (1)
set (p, "linewidth", 3)

You can get the color of the two other plots by referring to their handles:

get (q, "color")
get (r, "color")

Which will give you the RGB code for black (0,0,0) and green (0,1,0).

Have a look at all the properties of line objects:

get (q)

Some of those properties are read-only, while others have a limited set of allowed values. You may also want to look at modifiable properties and their allowed values:

set (q)

And set anything that is not to your taste to something else (for what's available see the manual).

set (p, "marker", "*")

Adding text() inside an axes() object is done by

text (2, 0.8, "HERE");

... but it now is inserted in figure 1, which might NOT be what you anticipated.

All low and high level plotting functions draw by default on the 'currentfigure' in the 'currentaxes' for which the handles can be retrieved using:

hfig = gcf (); # returns a handle to the current figure
hax = gca ();  # returns a handle to the current axes

In order to change the current figure/axes and draw in figure 2 you may either make them current using the the figure figure (NFIG) function:

figure (2) # figure 2 is now the current, let's check
get (0, "currentfigure")
haxes = get (gcf (),"children") # retrieve all axes handles
set (gcf (), "currentaxes", haxes(2)) # set the second axes current
text (1.0, 0.5, "THIS IS WHAT I WANTED")

... or explicitly specify the parent object in which you would like to draw the text:

haxes = get (2, "children") # retrieve all axes handles
text (1.0, 0.5, "THIS IS WHAT I WANTED", "parent", haxes (2))