Skip to main content
v2026.11,986 entries · CC-BY 4.0

surfc in MATLAB: 3D Surface Plots with Underlying Contours

Generate 3D surface plots with projected contour baselines in MATLAB using surfc, adjust surface and contour graphics handles, and troubleshoot grid matrices.

Written and maintained by CASRAI Editorial Board

Published

On this page

The surfc function in MATLAB generates a three-dimensional shaded surface plot with an integrated two-dimensional contour plot projected directly onto the lower horizontal plane of the axes. In scientific computing, numerical analysis, and empirical research, evaluating multidimensional data often requires understanding both continuous elevations and exact level boundaries simultaneously. By combining the topological visualization of a surface mesh with the quantitative threshold lines of a contour plot, surfc allows researchers to examine complex multivariate relationships within a single figure window without manually calculating and synchronizing separate coordinate layers.

What it is used for in research

Researchers routinely use surfc across physical sciences, engineering disciplines, and data-intensive fields where bivariate scalar functions or spatial measurements must be interpreted. Key research applications include:

  • Response surface methodology (RSM) and experimental optimization: Visualizing how an experimental outcome (such as chemical yield, enzymatic reaction rate, or aerodynamic drag) varies across two continuous control variables (such as temperature, reactant concentration, or fluid velocity). The projected contours immediately identify local optima, ridges, and saddle points.
  • Computational physics and transport phenomena: Plotting two-dimensional temperature fields, acoustic pressure distributions, or electric potential gradients across simulated physical geometries.
  • Machine learning and loss landscapes: Examining empirical loss surfaces, dual-parameter likelihood functions, and regularized objective functions during model diagnostics.
  • Geospatial and earth science modelling: Representing terrain elevations or subsurface geophysical measurements alongside topographic contour intervals.

Unlike standard 2D contour maps or unprojected 3D surfaces, matlab surfc displays elevation gradients and coordinate level curves in tandem. When structuring plotting routines for academic reports, researchers often pair these visual routines with standardized MATLAB figures management to preserve consistent aspect ratios, colorbars, and publication-ready resolutions across computational experiments.

Install or access (official source only)

The surfc command is a core built-in function in standard MATLAB, developed and maintained by The MathWorks, Inc. It does not require any specialized toolbox (such as the Statistics and Machine Learning Toolbox or Curve Fitting Toolbox) and operates out of the box in all supported commercial, academic, and student releases.

Official access routes provided by MathWorks include:

  • Desktop installation: Download and install the MATLAB desktop environment directly from the official MathWorks Account Portal (mathworks.com) using your institutional campus-wide license or individual named-user license.
  • MATLAB Online: Run scripts directly in a web browser via matlab.mathworks.com, which provides cloud-based access to the complete MATLAB desktop interface and graphics rendering engine.
  • High-Performance Computing (HPC) environments: Institutional clusters and research computing servers support headless and batch execution of MATLAB scripts containing surfc via Environment Modules (typically invoked with module load matlab) or through MATLAB Parallel Server.

Step-by-step task (numbered, with menu names or commands exactly as in the current docs)

Follow these numbered steps to generate a publication-ready 3D surface plot with an underlying contour projection from a parameterized bivariate dataset in a standard MATLAB code script or Live Script.

  1. Define the physical coordinate vectors and generate the evaluation grid: Create coordinate vectors representing the independent variables, then use meshgrid to generate full 2D evaluation matrices.
    % Step 1: Define domain vectors and build coordinate grids
    x = linspace(-3, 3, 60);
    y = linspace(-3, 3, 60);
    [X, Y] = meshgrid(x, y);
  2. Evaluate or load the dependent response variable: Calculate the dependent matrix Z over the coordinate matrices X and Y. In experimental workflows, Z can be loaded from laboratory measurements or simulation output files.
    % Step 2: Compute a continuous bivariate response surface
    Z = 3*(1 - X).^2 .* exp(-(X.^2) - (Y + 1).^2) ...
        - 10*(X/5 - X.^3 - Y.^5) .* exp(-X.^2 - Y.^2) ...
        - (1/3)*exp(-(X + 1).^2 - Y.^2);
  3. Call the surfc function and capture graphics handles: Execute surfc, assigning the return output to a variable array. This returns a two-element graphics array containing both the Surface object and the Contour object.
    % Step 3: Instantiate the plot and capture graphics handles
    figure('Name', 'Optimization Landscape', 'NumberTitle', 'off');
    sc = surfc(X, Y, Z);
  4. Configure surface transparency and contour styling: Access the individual graphics objects in the returned array (sc(1) for the surface and sc(2) for the contour) to optimize readability and prevent the upper surface from completely blocking the lower contour lines.
    % Step 4: Customize visual attributes via object properties
    sc(1).FaceAlpha = 0.85;          % Set surface transparency
    sc(1).EdgeColor = [0.25 0.25 0.25]; % Subtle mesh grid lines
    sc(2).LineWidth = 1.2;           % Emphasize projected contour isolines
  5. Annotate axes, add colorbar, and set viewing perspective: Complete the scientific figure with descriptive physical axis labels, units, a colormap scale, and an optimal 3D viewing angle.
    % Step 5: Finalize annotations and spatial orientation
    xlabel('Control Factor 1 (Concentration, mM)');
    ylabel('Control Factor 2 (Temperature, °C)');
    zlabel('Reaction Yield (%)');
    title('Response Surface with Projected Contours');
    colormap(parula);
    colorbar;
    view(-37.5, 30); % Azimuth and elevation angles
    grid on;

Output and how to read it

Executing surfc produces a combined dual-layer visualization containing two coordinated representations of the data:

  • Upper 3D surface mesh: Each quadrilateral facet is positioned at height Z(i, j) above the coordinate point (X(i, j), Y(i, j)). By default, face coloring maps directly to the numerical magnitude of Z using the active colormap (such as parula, viridis, or jet). This upper layer highlights peak response values, gradient steepness, and non-linear interactions between variables.
  • Lower projected contour lines: Directly below the 3D surface, a planar contour plot is projected onto the lower boundary plane of the axes (at the minimum z-axis limit, zmin). These isolines connect points of equal response value, allowing precise reading of thresholds, plateau boundaries, and contour intervals.
  • Interpreting gradient density: Regions on the bottom plane where contour lines are packed densely together represent steep slopes or rapid transitions in the response surface. Broad regions with sparse contour lines represent plateaus, basins, or gentle gradients.

To prepare the output for peer-reviewed publication or formal technical documentation, use exportgraphics(gcf, 'response_surface.pdf', 'ContentType', 'vector') to export crisp, scalable vector graphics rather than low-resolution screen captures.

Troubleshooting

When running surfc in automated analysis pipelines or data processing scripts, researchers frequently encounter specific dimensional and rendering issues. The following table outlines how to diagnose and correct them:

  • Error: “X and Y must be the same size as Z”:

    Cause: Passing 1D vectors directly to surfc(x, y, Z) when x and y are not matrices, or using inverted vector dimensions.

    Fix: Generate full 2D coordinate matrices using [X, Y] = meshgrid(x, y). Verify with size(X) == size(Z) and size(Y) == size(Z). Remember that if x has length N and y has length M, Z must have dimensions M × N.
  • Opaque surface hides projected contours:

    Cause: The default surface opacity (FaceAlpha = 1.0) blocks the observer’s line of sight to the bottom contour plane from certain viewing angles.

    Fix: Set sc(1).FaceAlpha = 0.8 (or lower) to render the 3D surface semi-transparent, or adjust the viewing angle using view(azimuth, elevation) so the base plane remains visible.
  • Contour lines clipping or overlapping the surface:

    Cause: Modifying axis limits with zlim after plotting can cause the bottom contour projection plane to clip or drift relative to data bounds.

    Fix: Explicitly specify the contour position by setting the contour object’s property sc(2).ZLocation = 'zmin' after defining custom axis limits, or add padding below the data minimum (for example, zlim([min(Z(:)) - 1, max(Z(:)) + 1])).
  • Rendering lag and large file sizes with dense meshes:

    Cause: Plotting high-resolution simulation grids (e.g., 500 × 500 points) creates over 500,000 polygonal edges, causing slow rotation and bloated vector files.

    Fix: Remove polygon edge rendering by executing sc(1).EdgeColor = 'none'; or subsample the grid resolution prior to plotting using downsampling strides (for instance, X_sub = X(1:5:end, 1:5:end)).

Free alternatives (table)

When proprietary commercial software licenses are unavailable or when collaborative workflows require open source software to ensure long-term computational reproducibility, several robust open-source tools provide equivalent 3D surface and contour visualization capabilities.

Tool / Environment License & Source Equivalent Function / Syntax Compatibility Notes
GNU Octave GNU General Public License v3+ (octave.org) surfc(x, y, z) Direct syntax drop-in replacement for MATLAB. Supports identical meshgrid generation, colormaps, and property settings. Ideal for automated batch scripts on Linux clusters without modification.
Python (Matplotlib / mplot3d) BSD-compatible PSF License (matplotlib.org) ax.plot_surface(X, Y, Z) and ax.contour(X, Y, Z, zdir='z', offset=zmin) Requires explicit 3D axis setup (projection='3d'). The contour projection is added via a separate ax.contour call with the offset parameter set to the lower axis boundary.
Scilab GNU General Public License v2 / CeCILL (scilab.org) plot3d(x, y, z) with contour2d Scientific numerical computing package. Surface generation uses plot3d; combining surface with underlying projected isolines requires multi-plot layering rather than a single unified command.

FAQ

What is the difference between surf and surfc in MATLAB?

The standard surf function generates only a 3D shaded surface plot. The surfc function generates the identical 3D surface mesh and automatically adds a 2D contour plot projected onto the bottom horizontal plane of the current axes (at zmin), allowing simultaneous reading of 3D elevations and 2D level curves.

How do I access and modify the contour lines in a surfc plot?

Capture the output when calling the function: sc = surfc(X, Y, Z);. This returns a two-element graphics array where sc(1) is the Surface object and sc(2) is the Contour object. You can then adjust contour properties directly, such as line width (sc(2).LineWidth = 1.5;) or line styling.

Can surfc handle non-uniformly spaced data grids?

Yes. As long as your independent coordinate vectors x and y are strictly monotonic (either strictly increasing or strictly decreasing), you can pass them to meshgrid(x, y) to produce coordinate matrices for surfc(X, Y, Z). For scattered or ungridded experimental data, interpolate the points onto a regular grid using griddata before calling surfc.

How do I make the surface translucent so contours beneath it remain visible?

Set the FaceAlpha property on the surface handle: sc = surfc(X, Y, Z); sc(1).FaceAlpha = 0.75;. Values between 0.0 (completely transparent) and 1.0 (completely opaque) allow the viewer to look through the upper peaks to inspect the underlying contour lines directly.

Sources (official docs)

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about surfc in MATLAB: 3D Surface Plots with Underlying Contours

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →