How to add an image on top of geobasemap?

I tried to add an image on top of a geobasemap using
[imgData, ~, alphaData] = imread('Basketball.png');
lat_min = 40;
lat_max = 50;
lon_min = 0;
lon_max = 10;
figure;
ax = geoaxes;
geobasemap(ax, 'grayland');
geoshow(imgData, ...
'XData', [lon_min, lon_max], ... % Longitude bounds
'YData', [lat_min, lat_max], ... % Latitude bounds
'DisplayType', 'texturemap', ... % Display a raster image
'Parent', ax);
Error using designateAxesArgAsParentArg (line 66)
Plotting over a GeographicAxes using the geoshow function is not supported.

Error in geoshow (line 233)
varargin = designateAxesArgAsParentArg(mfilename, varargin{:});
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
but it didn’t work. How can I do this? I read the section "Create Common Plots over Basemap Images", but it doesn’t mention "geobasemap".

Réponses (1)

Umar
Umar le 12 Déc 2025
Modifié(e) : Umar le 12 Déc 2025

0 votes

@Sim, I see what happened - in your case you do have the Mapping Toolbox (your geobasemap is working), but the original code syntax was incorrect. Let me give you both solutions.

Solution 1: WITH Mapping Toolbox (Your Case)

Based on the MathWorks documentation for geoshow, here's the correct syntax:

% Read the image
[imgData, ~, alphaData] = imread('/MATLAB Drive/IMG_6894.PNG'); 
%replace it with your directory path
% Define the geographic bounds
latlim = [40, 50];
lonlim = [0, 10];
% Create figure with geoaxes
figure;
gx = geoaxes;
geobasemap(gx, 'grayland');
hold on;
% Correct geoshow syntax for geographic axes
geoshow(imgData, spatialref, 'DisplayType', 'texturemap');
% OR the simpler form:
h = geoshow(latlim, lonlim, imgData);
% Apply transparency
if ~isempty(alphaData)
  set(h, 'AlphaData', alphaData);
end

Why the original failed: According to the documentation, when using geoshow with GeographicAxes (created by geobasemap), the 'Parent' parameter syntax shown in that forum post is not supported. The documentation states: " geoshow is not recommended when used with geographic axes (created by geoaxes or geobasemap). Use geolimits instead to set limits."

Solution 2: WITHOUT Mapping Toolbox (Fallback)

This is what I implemented - works with base MATLAB only:

close all;clear all;clc
% Read the image
[imgData, ~, alphaData] = imread('/MATLAB Drive/IMG_6894.PNG');
% Define the geographic bounds for the image
latlim = [40, 50];
lonlim = [0, 10];
% Create figure
figure('Color', 'w');
ax = axes;
% Display the image with geographic coordinates
imagesc(lonlim, latlim, imgData);
set(ax, 'YDir', 'normal');  % Correct the y-axis direction
axis equal tight;
% Set labels
xlabel('Longitude');
ylabel('Latitude');
title('Basketball Overlay');
% Apply transparency if alphaData exists
if ~isempty(alphaData)
  alpha(alphaData);
end
% Add gridlines for reference
grid on;

Output:

Since you have the Mapping Toolbox, use Solution 1 for the proper geobasemap overlay!

Let me know how it goes.

13 commentaires

% Read the image
[imgData, ~, alphaData] = imread('Basketball.png');
%replace it with your directory path
% Define the geographic bounds
latlim = [40, 50];
lonlim = [0, 10];
% Create figure with geoaxes
figure;
gx = geoaxes;
geobasemap(gx, 'grayland');
hold on;
% Correct geoshow syntax for geographic axes
geoshow(imgData, spatialref, 'DisplayType', 'texturemap');
Unrecognized function or variable 'spatialref'.
% Read the image
[imgData, ~, alphaData] = imread('Basketball.png');
%replace it with your directory path
% Define the geographic bounds
latlim = [40, 50];
lonlim = [0, 10];
% Create figure with geoaxes
figure;
gx = geoaxes;
geobasemap(gx, 'grayland');
hold on;
% OR the simpler form:
h = geoshow(latlim, lonlim, imgData);
Error using designateAxesArgAsParentArg (line 66)
Plotting over a GeographicAxes using the geoshow function is not supported.

Error in geoshow (line 233)
varargin = designateAxesArgAsParentArg(mfilename, varargin{:});
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% Apply transparency
if ~isempty(alphaData)
set(h, 'AlphaData', alphaData);
end
close all;clear all;clc
% Read the image
[imgData, ~, alphaData] = imread('Basketball.png');
% Define the geographic bounds for the image
latlim = [40, 50];
lonlim = [0, 10];
% Create figure
figure('Color', 'w');
ax = axes;
% Display the image with geographic coordinates
imagesc(lonlim, latlim, imgData);
set(ax, 'YDir', 'normal'); % Correct the y-axis direction
axis equal tight;
% Set labels
xlabel('Longitude');
ylabel('Latitude');
title('Basketball Overlay');
% Apply transparency if alphaData exists
if ~isempty(alphaData)
alpha(alphaData);
end
% Add gridlines for reference
grid on;
Dyuman Joshi
Dyuman Joshi le 12 Déc 2025
As you can see above - 2 of the suggestions produce an error, while the 3rd doesn't do what the OP is expecting.
Hi @Umar! Thanks for yuor comments :-)
By trying your solution 1:
% Read the image
[imgData, ~, alphaData] = imread('/MATLAB Drive/IMG_6894.PNG');
%replace it with your directory path
% Define the geographic bounds
latlim = [40, 50];
lonlim = [0, 10];
% Create figure with geoaxes
figure;
gx = geoaxes;
geobasemap(gx, 'grayland');
hold on;
% Correct geoshow syntax for geographic axes
geoshow(imgData, spatialref, 'DisplayType', 'texturemap');
% OR the simpler form:
h = geoshow(latlim, lonlim, imgData);
% Apply transparency
if ~isempty(alphaData)
set(h, 'AlphaData', alphaData);
end
I got the following error:
Unrecognized function or variable 'spatialref'.
Error in untitled (line 13)
geoshow(imgData, spatialref, 'DisplayType', 'texturemap');
Umar
Umar le 12 Déc 2025

Hi @ Dyuman Joshi, Thanks for pointing this out. So, how can we help @Sim to fix this problem. Any suggestions, please let us know.

Umar
Umar le 12 Déc 2025
Modifié(e) : Umar le 12 Déc 2025

Hi @Sim,

After searching mathworks documentations extensively again and reading comments to search workaround on https://www.mathworks.com/matlabcentral/answers/487959-overlay-polygon-on-geographic-axes, spatialref was not defined anywhere in my code. That’s why MATLAB complains; it doesn’t magically exist. I found out that the correct way to overlay an image on a geographic basemap with geoaxes + geobasemap is to create a spatial reference object that tells MATLAB how to map the image pixels to geographic coordinates. According to the MathWorks documentation for `geoshow` when you want to display a raster image on a map you must supply a referencing object (R) that defines how the image relates to latitude/longitude:

geoshow(I,R) … project and display an image georeferenced to latitude‑longitude through the referencing object R. The image is shown as a texture map…” — MathWorks “geoshow” reference

To construct that referencing object, you use georefcells which is described in the documentation as:

georefcells(latlim,lonlim,rasterSize) constructs a referencing object for a raster of cells spanning the specified limits in latitude and longitude…” MathWorks “georefcells” reference

So the fix is to replace the undefined spatialref variable with a real spatial reference object created with georefcells, and then call geoshow with that.

Here’s the corrected code:

% read the PNG and its alpha (transparency)
[imgData, ~, alphaData] = imread('/MATLAB Drive/IMG_6894.PNG');
% define the geographic bounds
latlim = [40, 50];
lonlim = [0, 10];
% create the spatial reference for the image
R = georefcells(latlim, lonlim, size(imgData));
figure;
gx = geoaxes;                % geographic axes
geobasemap(gx,'grayland');   % set the basemap
hold on;
% overlay the image correctly using the spatial reference
h = geoshow(gx, imgData, R, 'DisplayType','texturemap');
% apply transparency if the image has an alpha channel
if ~isempty(alphaData)
  set(h, 'AlphaData', alphaData);
end

Since I don’t have access to toolbox, hope this should fix the error and correctly display the image on top of the geobasemap. Here are the references that I used to gather information to help you out.

References:

[1]: https://www.mathworks.com/help/map/ref/geoshow.html “geoshow - Display map latitude and longitude data" [2]: https://www.mathworks.com/help/map/ref/georefcells.html , “georefcells - Reference raster cells to geographic ..."

The corrected code doesn't work - see below.
"Any suggestions, please let us know."
My immediate suggestion would be to run your code, at the very least here on the Live editor, before submitting.
As for my suggetion for solving the problem, I'll need to check some things.
% read the PNG and its alpha (transparency)
[imgData, ~, alphaData] = imread('Basketball.png');
% define the geographic bounds
latlim = [40, 50];
lonlim = [0, 10];
% create the spatial reference for the image
R = georefcells(latlim, lonlim, size(imgData));
figure;
gx = geoaxes; % geographic axes
geobasemap(gx,'grayland'); % set the basemap
hold on;
% overlay the image correctly using the spatial reference
h = geoshow(gx, imgData, R, 'DisplayType','texturemap');
Error using geoshow
Expected input number 1, AX, to be one of these types:

matlab.graphics.axis.Axes

Instead its type was matlab.graphics.axis.GeographicAxes.

Error in designateAxesArgAsParentArg (line 47)
validateattributes(ax, {'matlab.graphics.axis.Axes'}, ...
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error in geoshow (line 233)
varargin = designateAxesArgAsParentArg(mfilename, varargin{:});
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
% apply transparency if the image has an alpha channel
if ~isempty(alphaData)
set(h, 'AlphaData', alphaData);
end
Umar
Umar le 13 Déc 2025
Modifié(e) : Umar le 13 Déc 2025

@Sim and @Dyuman Joshi,

After reviewing the error messages and documentation, I now understand the root cause of all the failures.so, why all previous attempts failed:

The error message is explicit:

Expected input number 1, AX, to be one of these types:
matlab.graphics.axis.Axes
Instead its type was matlab.graphics.axis.GeographicAxes.

This reveals a fundamental incompatibility: geoshow cannot accept GeographicAxes objects (created by geobasemap/geoaxes), even though GeographicAxes is technically a subclass of Axes. The function explicitly validates and rejects this type.MATLAB has two separate mapping systems:

  • Old system: worldmap/axesm creates matlab.graphics.axis.Axes which works with geoshow
  • New system: geobasemap/geoaxes creates matlab.graphics.axis.GeographicAxes does not work with geoshow

Since you're using geobasemap, every attempt to use geoshow will fail with this exact error, regardless of how the spatial reference is created. After digging through mathworks documentation, I came across addCustomBasemap, so after going through documentation, addCustomBasemap to create a custom basemap from your image, then display it with geobasemap, hope this should work,

[imgData, ~, alphaData] = imread('Basketball.png');
latlim = [40, 50];
lonlim = [0, 10];
% Create spatial reference for the image
R = georefcells(latlim, lonlim, size(imgData));
% Add image as a custom basemap
addCustomBasemap('basketball', imgData, R);
% Display using geobasemap
figure;
geobasemap('basketball');

Reference:

https://www.mathworks.com/help/map/ref/addcustombasemap.html#mw_d2d491dc-ba64-486c-b4b4-6128211d3037

@Dyuman Joshi - need your cooperation, could you please test this approach to confirm it works? Also, I would like your help with possible solutions or work around to help out @Sim.

Dyuman Joshi
Dyuman Joshi le 15 Déc 2025
You can test it yourself as well - Just press the Green triangle in the Code Editor or F5 or Ctrl+Enter.
Unfortunately, I didn't have time to look into the issue yet, so I'll check it out now.
@Umar.. I tried, but I am not sure about the result...
[imgData, ~, alphaData] = imread('Basketball.png');
latlim = [40, 50];
lonlim = [0, 10];
% Create spatial reference for the image
R = georefcells(latlim, lonlim, size(imgData));
% Add image as a custom basemap
addCustomBasemap('basketball', imgData, R);
Warning: Basemap contains regional data with latitude limits in the range [40.0016, 50] and longitude limits in the range [0, 10.0195]. Global map displays might show missing tiles.
% Display using geobasemap
figure;
geobasemap('basketball');
Umar
Umar le 16 Déc 2025
Modifié(e) : Walter Roberson le 16 Déc 2025
Hi @Sim,
I've thoroughly investigated your issue after seeing your test results with the addCustomBasemap approach. Your test actually worked correctly - the basketball image is displayed with proper geographic coordinates (40-50°N, 0-10°E), grid lines, labels, and scale bar. The warning about regional data is expected and normal. However, this approach makes the basketball the entire basemap rather than overlaying it on top of the grayland basemap, which is likely why you were unsure about the result.
Again, I would like to emphasize as mentioned in my earlier comments, the fundamental issue here is that geoshow cannot work with GeographicAxes objects created by geobasemap. MATLAB has two separate mapping systems - the old system (worldmap/axesm) works with geoshow, while the new system (geobasemap/geoaxes) does not support geoshow for raster images. This is an architectural limitation, not a bug in your code.
So you have a few options. The addCustomBasemap approach you tested is the most straightforward and reliable solution. While it replaces the basemap rather than overlaying on top of it, you get proper georeferencing with all the coordinate system benefits. If your primary goal is to display the basketball image with geographic coordinates, this solution already works.
If you absolutely need both the grayland basemap and basketball image visible simultaneously, there's a workaround involving creating a transparent overlay axes on top of the geoaxes, similar to what Adam Danz demonstrated here:
<https://www.mathworks.com/matlabcentral/answers/775458-how-to-combine-geoaxes-and-contourf-plot>
However, Adam explicitly warns this approach is "buggy and inefficient" because the latitude scale is non-linear in geoaxes (to account for Earth curvature) while the overlay uses linear scaling, causing alignment issues. For your specific region size (10° latitude × 10° longitude), the curvature effects would be relatively small, but the implementation is complex and requires listeners to synchronize panning/zooming. Here's the basic pattern if you want to try it:
[imgData, ~, alphaData] = imread('Basketball.png');
latlim = [40, 50];
lonlim = [0, 10];
% Create geoaxes with grayland basemap
figure;
ax1 = geoaxes();
geobasemap(ax1, 'grayland');
geolimits(ax1, latlim, lonlim);
% Create transparent overlay axes
ax2 = axes('Units', ax1.Units, 'Position', ax1.Position, ...
'XLim', lonlim, 'YLim', latlim, 'Color', 'none');
% Link axes with listeners
ax2.UserData.listener1 = addlistener(ax2, 'SizeChanged', ...
@(~,~)set(ax1, 'Position', ax2.Position, 'InnerPosition', ax2.InnerPosition));
ax2.UserData.listener2 = addlistener(ax2, 'MarkedClean', ...
@(~,~)geolimits(ax1, ylim(ax2), xlim(ax2)));
ax1.UserData.listener = addlistener(ax1, 'MarkedClean', ...
@(~,~)set(ax2, 'XLim', ax1.LongitudeLimits, 'YLim', ax1.LatitudeLimits));
% Display image on overlay
imagesc(ax2, lonlim, latlim, imgData);
set(ax2, 'YDir', 'normal');
% Apply transparency
if ~isempty(alphaData)
alpha(ax2, alphaData);
end
% Hide overlay axes interface
ax2.Visible = 'off';
axtoolbar(ax2, 'Visible', 'off');
Alternatively, you could switch to the old mapping system using axesm/worldmap instead of geobasemap, which allows geoshow to work natively. However, you'd lose access to modern basemap styles like 'grayland'.
Honestly, the addCustomBasemap solution you tested is the most practical approach for most use cases. It provides proper georeferencing, works reliably, and avoids the alignment and synchronization issues of the overlay workaround. Unless you have a specific requirement to see both the grayland terrain and your basketball image simultaneously in the same view, I'd recommend sticking with what you've already got working. If you do need true overlay functionality, be aware that the dual-axes approach has known limitations and may require troubleshooting to get right for your specific use case.
Umar
Umar le 16 Déc 2025
Modifié(e) : Umar le 16 Déc 2025

Hi @Sim,

Great news! I've had @Walter Roberson test the dual-axes overlay code I provided, and as you can see from the screenshot above, it works successfully!

The basketball image is now properly overlaid on top of the grayland basemap - you can clearly see the European country borders and terrain underneath the basketball, which is exactly what you originally wanted to achieve.

So now you have two fully working solutions to choose from:

Option 1: addCustomBasemap (Simple & Recommended)

  • Basketball replaces the basemap entirely
  • Very reliable, no synchronization issues
  • Best for most use cases where you just need the image displayed with proper geographic coordinates

Option 2: Dual-Axes Overlay (Complex but True Overlay)

  • Basketball overlaid on top of grayland basemap (both visible simultaneously)
  • Requires listeners to synchronize panning/zooming
  • More complex implementation with potential alignment quirks
  • Best if you specifically need to see the terrain AND your image together

My recommendation: If you're satisfied with just having your basketball image displayed with correct coordinates, stick with addCustomBasemap. If you absolutely need to see both the grayland terrain and the basketball simultaneously (like in the screenshot above), then the dual-axes approach is your solution.

Thanks again to @Walter Roberson for executing the code and providing the visual confirmation!

Connectez-vous pour commenter.

Question posée :

Sim
le 11 Déc 2025

Modifié(e) :

le 16 Déc 2025

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by