Graphics Objects and Customization
|
This content was generated with the assistance of AI and should be verified against the official documentation before being relied on in production. The reference material consulted while preparing these pages is listed in the section bibliography. |
Written against MATLAB R2026b. A figure needs a graphical environment, so the MATLAB code on this page was not run here. GNU Octave 11.3.0 was used to check the parent-child structure and the effect of set, findobj and delete; that output is labelled Octave 11.3.0 output. Octave’s graphics handles are plain numbers, whereas MATLAB’s are objects, which the section on dot notation explains; the code that calls set and get runs in both.
Every chart in 2-D Plotting and 3-D Plotting and Surfaces is a tree of graphics objects. Knowing the tree turns the question of how to change a detail of a chart into a question of which object has which property.
Terminology
-
A graphics object is one visual component with properties: a figure, an axes, a line, a text label, a legend.
-
A handle is a reference to a graphics object, returned by the function that created it. Copying a handle does not copy the object. (This is the same idea as a handle class, and graphics objects are in fact handle objects.)
-
The hierarchy is the containment of objects: parents contain children.
ParentandChildrenare properties that hold the links. -
The root is the single object at the top, the graphics root, returned by
groot. Its children are the open figures. -
A property is a named setting of an object, for example
Color,LineWidth,XData. Most properties accept a name-value pair when the object is created. -
A theme (R2025a) is the light or dark colour scheme of a figure.
The object hierarchy
When you call plot, MATLAB creates (or reuses) a figure, creates (or reuses) an axes inside it and creates a line object inside the axes. An axes is one object that represents the x-, y- and z-axis scales, the tick marks, the tick labels and the axis labels; the labels and the title are objects owned by the axes. The figure also contains objects that are not in the axes, such as a legend, a colorbar, a tiled chart layout or interface components.
The same containment can be read from the objects. The Children of an axes hold its lines, the Parent of a line is the axes, and the Parent of an axes is the figure (or a tiled chart layout, which is then the child of the figure).
Octave 11.3.0 (code run as written; the same calls exist in MATLAB):
fig = figure("visible","off");
t = (0:60:600)/60;
T1 = 21 + 1.5*(1-exp(-t/4));
T2 = 21 + 0.9*(1-exp(-t/6));
h = plot(t, T1, "-o", t, T2, "--s");
ax = gca;
fprintf("class(h) = %s, numel(h) = %d\n", class(h), numel(h));
fprintf("type of h(1): %s, type of ax: %s, type of fig: %s\n", get(h(1),"type"), get(ax,"type"), get(fig,"type"));
set(h(1), "LineWidth", 2);
fprintf("LineWidth = %g\n", get(h(1),"LineWidth"));
fprintf("axes is parent of lines: %d\n", isequal(get(h(1),"parent"), ax));
fprintf("figure is parent of axes: %d\n", isequal(get(ax,"parent"), fig));
fprintf("ishghandle(h): %s\n", mat2str(ishghandle(h)'));
fprintf("gca equals ax: %d, gcf equals fig: %d\n", isequal(gca, ax), isequal(gcf, fig));
found = findobj(ax, "Type", "line");
fprintf("findobj lines: %d\n", numel(found));
xlabel("Time (min)"); ylabel("Temperature (degC)");
s = get(get(ax,"xlabel"),"string");
fprintf("xlabel: %s\n", s);
delete(h(2));
fprintf("valid after delete: %s\n", mat2str(ishghandle(h)'));
fprintf("kids of axes: %d\n", numel(get(ax,"children")));
close(fig);
Octave 11.3.0 output (a warning about Octave’s gnuplot toolkit printed first is omitted):
class(h) = double, numel(h) = 2
type of h(1): line, type of ax: axes, type of fig: figure
LineWidth = 2
axes is parent of lines: 1
figure is parent of axes: 1
ishghandle(h): [true true]
gca equals ax: 1, gcf equals fig: 1
findobj lines: 2
xlabel: Time (min)
valid after delete: [true false]
kids of axes: 1
The output confirms the tree: two lines are children of the axes, the axes is a child of the figure, gca and gcf return the objects that were just created, the label is stored on a child object of the axes, and deleting one line leaves its handle in the array but marks it invalid. The first line is where Octave and MATLAB differ: in Octave class(h) is double, in MATLAB it is matlab.graphics.chart.primitive.Line, not run here.
Handles: set, get and dot notation
Every plotting function can return its object or objects. A call with one series returns a scalar; with several series, an array.
h = plot(t, [T1' T2']); % h is a 2-by-1 array of Line objects
c = h(1).Color; % read a property
h(1).LineWidth = 2; % set it
h(2).LineStyle = "--";
set(h, "Marker", "o") % set the same property on every object of an array
ax = gca;
ax.Title.String = "Sensors"; % a property that holds another object
ax.Title.FontWeight = "normal";
v = get(h(1), "YData"); % the older function form
Not run here. In MATLAB, h(1).Color is a 1-by-3 RGB triplet (the documentation shows [0 0.4470 0.7410] for a default line); the default colours of the light theme changed slightly in R2025a, so do not hard-code the value.
The two forms:
-
Dot notation,
object.PropertyName, reads a property,object.PropertyName = valuesets it, and several dots reach properties of objects held in properties (ax.Title.FontWeight). For a non-scalar variable, index first (h(1).LineStyle). The release that introduced dot notation for graphics objects (R2014b, the release that made handles objects) is not stated on the documentation pages consulted; code that must run before it has to usesetandget. -
set(h,"Name",value)andget(h,"Name")are older. They still work in R2026b, accept an array of handles (set(h,"LineStyle","--")sets all of them), andset(h)orget(h)with one argument lists the properties. The property names insetandgetare not case-sensitive, while dot notation is. -
Name-value pairs at creation are shortest:
plot(t,T1,LineWidth=2,Color="r").
With dot notation, end indexing appends to data properties such as XData and YData, which is the basis of the animation below. Ensure the x and y data stay the same size before the next redraw.
A handle is a reference
h = plot(1:10);
h2 = h; % a second variable referring to the same line
h2.Color = [1 0 0]; % h.Color is now [1 0 0] too
close gcf % deletes the figure and its children
isvalid(h) % false: the variable still exists but the object is gone
h.Color % error: invalid or deleted object
Not run here. A handle copy does not copy the line, and after the figure is closed every variable that referred to its objects stays in the workspace but is invalid. isvalid(h), isgraphics(h) (R2014b) and ishandle(h) test a handle; delete(h) removes an object, and clf and cla delete the children of a figure or an axes. To copy an object use copyobj.
Source: MATLAB documentation: isgraphics
Finding objects: gcf, gca, groot, findobj
| Function | Returns |
|---|---|
|
The current figure and current axes. They create one if none exists. |
|
The root object; |
|
The objects below |
|
The nearest ancestor of a given type. |
|
Whether the variable refers to a valid graphics object of that type. |
The earlier Octave output shows findobj returning the two lines of the axes. A common fragment tags a series so that it can be found again and updated:
plot(t, T1, Tag="S1")
line1 = findobj(gca, "Tag", "S1");
line1.LineWidth = 3;
Not run here. findobj returns a handle to the line created with Tag="S1" and the second line widens it.
Source: MATLAB documentation: findobj
Customizing a chart
t = (0:30)';
S1 = 20 + 6.0*(1 - exp(-t/8));
fig = figure;
h = plot(t, S1, "o-", LineWidth=1.5, MarkerSize=5, MarkerFaceColor="auto");
ax = gca;
ax.FontSize = 12;
ax.XGrid = "on";
ax.YGrid = "on";
ax.XLim = [0 30];
ax.YLim = [19 27];
ax.XTick = 0:5:30;
ax.Title.String = "Sensor S1";
ax.XLabel.String = "Time (min)";
ax.YLabel.String = "Temperature (\circ C)";
[~, imax] = max(S1);
text(t(imax), S1(imax), " maximum", VerticalAlignment="top")
annotation("textarrow", [0.6 0.75], [0.35 0.45], String="settling")
Not run here. The chart shows S1 as a line with circles, a grid, fixed limits, ticks every 5 minutes, a title and labels, a small text label next to the last point and an arrow with the text "settling" in figure coordinates (the two numbers in each pair are normalized positions in the figure, between 0 and 1).
text(x,y,txt) puts text at a data point inside the axes, in data units, and it scales with the axes. annotation draws arrows, lines, ellipses, rectangles and text boxes in the figure, at normalized coordinates, so it does not move with the data; use text, xline or yline for anything that belongs to a data value.
Many properties are common to all objects, and the full lists are the property pages of each object class (Line Properties, Axes Properties, Figure Properties):
| Object | Frequently used properties |
|---|---|
|
|
|
|
|
|
Default values
The root object holds default values that are applied to every object created afterwards. The name of such a property combines default, the object type and the property name.
set(groot, "defaultLineLineWidth", 2) % all lines created from now on
set(groot, "defaultAxesFontSize", 12)
set(groot, "defaultFigureColor", "w")
plot(1:5) % uses the defaults
set(groot, "defaultLineLineWidth", "remove") % back to the factory value
Not run here. The chart is drawn with 2-point lines and 12-point axes text. The defaults last for the session; put them in startup.m (see The Search Path, Startup and Files) to keep them. The release notes for R2025a say that some default colours changed; setting the defaults explicitly keeps figures the same across releases.
Figures, tabs and themes
-
The desktop introduced in R2025a (see Desktop and Command Window) opens figures as tabs in the document area. In R2026b, figures created with
figurethat have a menu bar or a toolbar no longer support docking into the desktop, whileuifigurefigures still do. -
Themes (R2025a). A figure is light or dark.
theme(fig,"dark"),theme(fig,"light")ortheme(fig,"auto")set it, andgt = theme(fig)returns aGraphicsThemeobject with the propertiesNameandBaseColorStyle. By default a figure follows the theme of the desktop, and colours chosen by MATLAB adapt to it (the "gem" palette is the light default, "glow" the dark default). Colours you set explicitly are not changed, so choose them with the theme in mind.exportgraphicstakes the background from the theme when it is not set (see Exporting Figures and Images). -
Since R2025a, the Figure Palette, Plot Browser, Property Editor and
plottoolswere removed or incorporated into the toolstrip, sofigurepalette,plotbrowser,propertyeditor,propeditandplottoolsreturn an error. Use plot edit mode with the Property Inspector (inspect(h)opens it for an object) instead.
Source: MATLAB documentation: theme
Animation with drawnow
MATLAB redraws graphics when the program is idle, at the end of a command, or when drawnow is called. A loop that changes a property and does not yield shows only the last state. drawnow flushes the queue; drawnow limitrate limits the redraw rate for speed, and pause(s) also yields. Update the properties of an existing object instead of calling plot in each iteration, which would create new objects every time.
The heatflow simulation produces one temperature per step for the sensor at the plate centre. This sketch animates it without a plate solver, using a closed form for the sensor:
nSteps = 60;
h = plot(0, 20, "-o");
xlim([0 nSteps])
ylim([19 27])
xlabel("Step")
ylabel("Temperature (\circ C)")
for k = 1:nSteps
h.XData(end+1) = k;
h.YData(end+1) = 20 + 6.0*(1 - exp(-k/16));
drawnow limitrate
end
Not run here. A line grows from the point (0, 20) and levels near 26 degrees Celsius as the loop runs. Each iteration appends one point to XData and YData of the same object, so the loop does not create new lines, and drawnow limitrate keeps the redraw cost low. The two assignments are consistent in size by the time the redraw happens.
animatedline (R2014b) is built for this: an = animatedline; addpoints(an,x,y); drawnow. It keeps memory bounded with MaximumNumPoints. getframe captures a frame for a movie, and exportgraphics(ax,"file.gif",Append=true) makes a basic animated GIF from charts with the same axes limits (see Exporting Figures and Images).
Source: MATLAB documentation: drawnow
Common errors and pitfalls
The messages were not run here; the causes are documented behaviour.
-
Using a deleted handle. After
closeordelete,h.Colorraises an error about an invalid or deleted object. Test withisvalid(h)orisgraphics(h)before use. -
gcaandgcfcreate objects. A script that callsgcaafter closing all figures opens a new empty figure and axes. Keep your own handles (ax = nexttile,fig = figure) and pass them as the first argument:plot(ax,...),title(ax,...). -
Setting a property on an array with dot notation.
h.Color = "r"fails whenhhas several elements. Index (h(1).Color), loop, or useset(h,"Color","r"). -
Axes properties revert. With the default
NextPlotvalue of"replace", a newplotcall deletes the children and resets most axes properties, such as limits that you had set. Set limits after plotting, or usehold onto keep the axes as they are. -
Slow animation. Calling
plotinside the loop creates and deletes objects. UpdateXDataandYDataof one object and calldrawnow limitrate. -
Objects in Octave. An Octave handle is a number:
h.LineWidth = 2is an error there, and code that must run in both systems usessetandget. -
Property names.
set(h,"linewidth",2)works, buth.linewidthdoes not: dot notation is case-sensitive.
Where older books differ
-
Before R2014b graphics handles were doubles, and every book of that period writes
set(h,"Color","r"),get(h,"Children")andgcfas numbers (figure(1)still selects figure 1). The current objects accept both forms, and the type is a class such asmatlab.graphics.chart.primitive.Line. -
Books from before R2014b describe
hggroup,uipanelanduicontroltrees; many of the interactive tools they describe were removed or replaced (see the R2025a bullet above). -
Standalone charts such as
heatmap,piechartanddonutchartare not axes children: they sit directly in a figure or layout and have their own properties instead of an axes. Newer plotting functions such asboxchartandswarmchartdo create objects in an axes. Neither group appears in the older books. Dark themes and thethemefunction are new in R2025a. -
Defaults changed in R2014b (new colour order,
parula) and in R2025a (new light palette, themes), so screenshots in older books differ from today’s output.