Back to Blog

How to Plot in MATLAB: Create, Style, and Export Figures

Published04/03/2026
Updated 07/23/2026
15 min read

A 3-D wave surface rendered in RunMat

Plotting in MATLAB syntax follows a dependable workflow: create numeric data, choose a representation, then label and refine the figure. This guide works through that workflow in RunMat, from a sampled function to multiple series, subplots, 3-D graphics, animation, and image export.

The examples use MATLAB-compatible syntax and run directly from each code block. You can also open the RunMat sandbox for a temporary browser workspace or RunMat Desktop when you want to work from a local folder. If your question is which representation fits the data, use the guide to choose the right MATLAB plot type, then browse the rendered examples in the MATLAB Plot Gallery.

MATLAB function plots start with sampled coordinates

A plotting function needs coordinates. Sample the function over a domain, evaluate it with element-wise operators, and pass the resulting vectors to plot. The first vector supplies the horizontal coordinates and the second supplies the vertical coordinates.

x = linspace(0, 2*pi, 240);
y = sin(x) .* exp(-0.08*x);

plot(x, y, 'LineWidth', 2);
title('Damped sine function');
xlabel('x');
ylabel('sin(x)e^{-0.08x}');
grid on;

This pattern works for measured equations as well as analytic functions. Use .^, .*, and ./ when the expression operates on every sampled value independently. Functions of two variables can be sampled over a grid and displayed with fcontour, fsurf, or the grid-based methods later in this guide.

RunMat Desktop displaying MATLAB-compatible sine and cosine plotting code, workspace variables, and the resulting labelled figure.

RunMat Desktop keeps the script, rendered figure, and resulting workspace variables together while you iterate on a plot.

Coordinates define functions, paths, and independent observations

The coordinates can describe a function, a geometric path, or isolated observations. A line style connects neighboring values; a marker-only style leaves them independent. scatter adds per-point size and color when those encodings belong to the data.

These compact forms cover several common plotting tasks:

TaskMATLAB-compatible syntaxWhat it represents
Plot a single pointplot(3, 5, 'o')One marked coordinate
Plot a straight linex = 0:0.1:10; plot(x, 2*x + 1)Samples from (y = 2x + 1)
Plot a circlet = linspace(0, 2*pi, 240); plot(cos(t), sin(t)); axis equalA parameterized closed curve
Plot independent pointsscatter(x, y)Observations with no connecting path
Plot a piecewise functiony = (x < 0).*(-x) + (x >= 0).*sqrt(x); plot(x, y)A function evaluated by region

Choose marker-only points when connecting segments would imply an order that the data does not have. Keep a line when adjacency is part of the result.

hold puts multiple lines on the same axes

Use hold to retain the current axes while adding another series. A legend identifies the series, while labels state what the coordinates measure.

x = linspace(0, 2*pi, 240);

plot(x, sin(x), 'LineWidth', 2);
hold on;
plot(x, cos(x), '--', 'LineWidth', 2);
hold off;

legend('sin(x)', 'cos(x)');
title('Two functions on one set of axes');
xlabel('Angle (rad)');
ylabel('Amplitude');
grid on;

The axes now contain two plot objects. Keeping both series in one coordinate system supports direct comparison; separate subplots are better when their scales or visual forms would interfere with each other.

Handles and reference lines control figure styling

Plot handles let you change a specific object after it exists. Pass a handle to set to update line width, color, markers, or display name. Use xline and yline for events, limits, targets, and other reference values.

x = linspace(0, 10, 200);
y = 1 - exp(-0.65*x);

h = plot(x, y);
set(h, 'LineWidth', 2.5, 'Color', [0.05 0.48 0.78]);

yline(0.9, '--r', '90% target');
xline(4, ':k', 'Review time');
title('Response with reference lines');
xlabel('Time (s)');
ylabel('Normalized response');
xlim([0 10]);
ylim([0 1.1]);
grid on;
box on;

Reference lines are annotations rather than primary plot types. Add them after the main representation is clear, and label them when the value would otherwise be ambiguous.

Common axes commands include title, xlabel, ylabel, grid, xlim, ylim, axis, and box. The figure-state documentation explains how these commands update the active axes and graphics objects.

subplot divides a figure into an indexed grid of axes. Each plotting call applies to the selected cell until another subplot becomes active.

x = linspace(0, 2*pi, 160);
[X, Y] = meshgrid(linspace(-2.5, 2.5, 50));
Z = sin(X) .* cos(Y);

subplot(2, 2, 1);
plot(x, sin(x), 'LineWidth', 1.8);
hold on;
plot(x, cos(x), '--', 'LineWidth', 1.8);
hold off;
title('Multiple lines');
grid on;

subplot(2, 2, 2);
scatter(cos(x), sin(x), 24, x, 'filled');
title('Point coordinates');
axis equal;

subplot(2, 2, 3);
contourf(X, Y, Z, 14);
title('Scalar-field regions');
colorbar;

subplot(2, 2, 4);
surf(X, Y, Z);
shading interp;
title('Scalar-field height');
view(42, 28);

The layout compares related results without forcing them into one axes object. Keep labels and titles short enough to remain readable when each panel becomes smaller.

A 2x2 RunMat subplot figure combining styled lines, scatter points, a scalar field, and a 3-D surface.

One figure can arrange related line, point, contour, and surface views while preserving separate axes for each representation.

Imported numeric columns use the same plotting calls

Imported measurements use the same plotting calls once the file columns are numeric arrays. readmatrix reads tabular numeric data, after which you can select the columns that define the axes.

data = readmatrix('test_run.csv', 'NumHeaderLines', 1);
time = data(:, 1);
temperature = data(:, 2);

plot(time, temperature, 'LineWidth', 1.5);
xlabel('Time (s)');
ylabel('Temperature (deg C)');
title('Recorded test run');
grid on;

Check the file's units, missing values, and sample ordering before interpreting the figure. The CSV guide covers import options and validation in more detail.

3-D data can represent surfaces, trajectories, points, or vector fields

A gridded scalar field supports several views. surf renders filled faces and treats values as height. mesh keeps the sampled grid visible as a wireframe.

[X, Y] = meshgrid(linspace(-3, 3, 70));
R = sqrt(X.^2 + Y.^2) + 0.05;
Z = sin(3*R) ./ R;

subplot(1, 2, 1);
surf(X, Y, Z);
shading interp;
title('Filled surface');
view(45, 30);

subplot(1, 2, 2);
mesh(X, Y, Z);
title('Visible sample grid');
view(45, 30);

Use the filled surface when continuous shape is primary. Use the mesh when the sampling lattice helps explain the result.

For spatial coordinates, plot3 connects an ordered path and scatter3 leaves observations independent.

t = linspace(0, 8*pi, 300);
x = cos(t);
y = sin(t);
z = 0.08*t;

subplot(1, 2, 1);
plot3(x, y, z, 'LineWidth', 2);
title('Connected 3-D trajectory');
xlabel('x');
ylabel('y');
zlabel('z');
grid on;

subplot(1, 2, 2);
scatter3(x, y, z, 22, t, 'filled');
title('Independent 3-D points');
xlabel('x');
ylabel('y');
zlabel('z');
grid on;

Use 3-D when the third coordinate belongs to the analysis. Camera position and occlusion affect how the reader sees the result, so label every axis and inspect more than one view.

quiver plots direction and magnitude at positions in a two-dimensional domain. Its 3-D counterpart is quiver3.

[X, Y] = meshgrid(-2:0.4:2);
U = -Y;
V = X;
speed = sqrt(U.^2 + V.^2);

contourf(X, Y, speed, 12);
hold on;
quiver(X, Y, U, V, 'k');
hold off;

title('Rotational vector field');
xlabel('x');
ylabel('y');
axis equal;
colorbar;

The filled contours show vector magnitude; the arrows preserve direction. Both quantities come from the same field.

drawnow updates animation frames before display or export

drawnow presents pending graphics updates inside a loop. Reuse one figure and keep the grid modest when the purpose is to inspect motion rather than benchmark rendering.

[X, Y] = meshgrid(linspace(-3, 3, 55));
R = sqrt(X.^2 + Y.^2) + 0.1;

for frame = 1:36
    Z = sin(3*R - frame*0.22) ./ R;
    surf(X, Y, Z);
    shading interp;
    colormap('turbo');
    view(45, 30);
    zlim([-3 3]);
    title('Animated radial wave');
    drawnow;
end

RunMat keeps figure objects, axes, plot elements, labels, limits, and camera-related state in a graphics scene. The active host renders that state to an interactive display or a fixed image.

Loading diagram...

In RunMat Desktop, open the figure's graphical actions and choose the save-image control to write the visible figure as an image. This captures the current view without adding export code to the script. Use scene replay when the result must reopen as editable graphics state rather than fixed pixels.

To experiment without setting up a project, open the RunMat sandbox and change one of the examples above. For work that already lives in local files, open its folder in RunMat Desktop, run the script, inspect the variables and figures, then save the view you want to share.

Frequently asked questions

How do I make a basic plot in MATLAB?⌄

Create vectors for the horizontal and vertical coordinates, then call plot(x, y). Add a title, axis labels, and a grid after the plotting call.

How do I plot a function or equation?⌄

Sample the input domain with linspace or the colon operator, evaluate the expression with element-wise operators, and plot the two resulting vectors. For a function of two variables, use a grid with surf or mesh, or use fcontour and fsurf when their supported call forms fit the function.

How do I plot multiple lines on the same graph?⌄

Plot the first series, call hold on, plot the remaining series, then call hold off. Use legend to identify the lines.

How do I show multiple graphs in one figure?⌄

Use subplot(rows, columns, index) before each plotting call. Each index selects one axes position in the layout.

How do I add a horizontal or vertical line?⌄

Use yline(value) for a horizontal reference and xline(value) for a vertical reference. These lines work well for thresholds, event times, and target values.

How do I plot data imported from a file?⌄

Read the numeric data with readmatrix, assign the required columns to vectors, and pass those vectors to plot, scatter, or another suitable plotting function. Validate units and missing values before interpreting the figure.

Can I run these examples in the browser or on my desktop?⌄

Yes. Each runnable block opens in the RunMat browser workspace. You can also copy the code into a .m file in a local RunMat Desktop folder and run it against local data.

How do I save a plot as an image in RunMat Desktop?⌄

Open the figure actions in RunMat Desktop and use the graphical save-image control. The exported image records the visible figure; scene replay preserves editable graphics state for later use.

Enjoyed this post? Join the newsletter

Monthly updates on RunMat internals, development, and performance tips.

Download RunMat

Download RunMat for full performance, or use RunMat in your browser for zero setup.