How do I plot a circle on a Matlab figure?

I want to plot a circle with blinking effect on a Matlab figure. I want this marker on the simulation to have a blinking effect everytime my readings are above threshold value. Is there any function or way to achieve this?
So far I have tried:
Using this creates a separate figure, which I don't want:
plot(0,0,'ro','MarkerSize',10,'MarkerFaceColor','r','MarkerEdgeColor','r');
I want to create a plot on the figure which is created by this code:
viewer = trackingGlobeViewer('Basemap','streets-dark',...
'TrackLabelScale',1.3,'TrackHistoryDepth',4000,...
'CoverageMode','Coverage');
For instance I want to plot a marker at the bottom right of this figure generated by the above code.
EDIT:
Thank you!

Answers (2)

Hi,
The trackingGlobeViewer is based on the same technology as geoglobe from the Mapping Toolbox. Globe based visualizations are not like the usual MATLAB graphics plots, you cannot use 'plot' to overlay graphics on top of a globe.
If you have the Mapping Toolbox, you can use geoplot3 instead.
First create the trackingGlobeViewer as in the example:
viewer = trackingGlobeViewer('Basemap','streets-dark',...
'TrackLabelScale',1.3,'TrackHistoryDepth',4000,...
'CoverageMode','Coverage');
To retrieve the geoglobe object you can use either one of the following lines of code:
globe = findall(groot, 'type', 'globe');
globe = viewer.Globe; %Undocumented
% Next plot markers with geoplot3
% geoplot3(globe, ...)

2 Comments

Can I use Geoplot to plot a text or a marker that alywas stays at a particular position on my tackGlobeViewer??
Yes you can plot a marker with geoplot3, it would look like this for instance (see the documentation link from my previous post for more details).
geoplot3(globe, 71,-42,10,'Color','r','MarkerSize',13,'Marker','o');
Note that by default, the geoplot3 command will move the globe camera to the location of the markers. If you do not want this behavior, you can disable it by setting the camera modes to manual like this:
% Disable camera first
campitch(globe,'manual')
camroll(globe,'manual')
camheading(globe,'manual')
campos(globe,'manual')
camheight(globe,'manual')
% Plot marker
geoplot3(globe, 71,-42,10,'Color','r','MarkerSize',13,'Marker','o');
The marker will stay at this particular location on the globe, because the default option for NextPlot is 'add'. If you need to clear the marker, you can set NextPlot to 'replace'.
There is currently no capability to display text on the globe, but I can pass along this information to the Mapping Toolbox team.

Sign in to comment.

plot(0,0,'ro','MarkerSize',10,'MarkerFaceColor','r','MarkerEdgeColor','r');
That could have several different effects.
  • If you have no figures of any kind opened, or if you do have figures open but none of them are the "current" figure, then a new traditional figure would be opened and a new axes placed in the new traditional figure, and the marker would be plotted in that axes
  • If you have uifigure() open but not traditional figures, then by default the handle visibility is set off for uifigure() so plot() would not be able to locate the uifigure as being the current figure; this then becomes the same as the above where a new traditional figure is created
  • if you have a "current" (visible) figure that has no "current" axes, then a new axes would be created in the figure and the marker would be plotted in the new axes
  • if you have a "current" (visible) axes whose "NextPlot" property is set to "replace" (the default if you have not used "hold on") then the axes will be cla() but not cla('reset') -- the plot of the marker would replace the current plot
  • if you have a "current" (visible) axes whose "NextPlot" is not "replace" then the plot of the marker would be added at layer z = 0 without removing any current drawing
These days the most common reason that a plot() creates a new figure is if you are using App Designer: when you use App Designer you should always tell plot() explicitly which existing axes you want to draw into (because the handle visibility of the UIAxes will be off and plot() will not be able to find the axes when it does gca() )

14 Comments

Anyhow, depending on the size of the circle you want, you could use any of plot or scatter or viscircles -- with viscircles being better for drawing larger more-accurate circles.
I just want a small circle that can act as an indicator/alert. So I understood from your answer why plot() creates new figure instead of writing to the traditional figure. But whats the workaround to plot on the tradtional figure? Is there any way to avoid plot() creating a new figure window instead just plotting on the specifc location on the already existing figure?
Thank you for the detailed reply.
As an alternative, Is there any way to display a text on the existing figure that can be updated everytime for the duration of the Simulation? (I understand this is a new question. If this is possible, I will edit my original question.)
The text can be something as simple as: Alert! Current Value <valuethatChanges> crossed the threshold.
If your existing plot is based on a traditional figure, then plot() with the parameters you call would not create a new figure unless it could not find the existing traditional figure (because the handle visibility was turned off or because another figure was set(groot, 'CurrentFigure') and then that other figure was deleted, leaving no CurrentFigure)
The best thing to do is explicitly pass the handle of the axes you are plotting into.
hold(ax, 'on')
h = plot(ax, 0,0,'ro','MarkerSize',10,'MarkerFaceColor','r','MarkerEdgeColor','r');
hold(ax, 'off')
I would suggest doing that once, and then h.Visible = 'on' or h.Visible = 'off' as needed (provided that you are updating the current contents rather than replacing it each time.)
template = 'Alert! Current Value %g crossed the threshold';
texth = text(xlocation, ylocation, '<empty>', 'visible', 'off');
....
if valuethatChanges > threshold
texth.String = sprintf(template, valuethatChanges);
texth.Visible = 'on';
else
texth.Visible = 'off')
end
Thank you. Is there any way to obtain the axes. I ran the example but couldnt find any x, y location or axes that I can use. Or am I supposed to have my own X Y locations?
Unfortunately I do not have access to that toolbox.
Could you add a ReferenceLocation corresponding to the lower left?
Could you show the output of
viewer = trackingGlobeViewer('Basemap','streets-dark',...
'TrackLabelScale',1.3,'TrackHistoryDepth',4000,...
'CoverageMode','Coverage');
orderfields(struct(viewer))
EDIT:
This is the output. Please let me know if there is anything else I can provide. Thank you!
Hmmm, could you show
orderfields(struct(viewer.Globe))
orderfields(struct(viewer.Viewer))
Warning: Calling STRUCT on an object prevents the object from hiding its implementation details and should thus be
avoided. Use DISP or DISPLAY to see the visible public details of an object. See 'help struct' for more information.
> In OspaCalc (line 71)
ans =
struct with fields:
ApplicationData: [1×1 struct]
Basemap: 'streets_dark'
BasemapMode: 'manual'
Basemap_I: "streets_dark"
CameraHeading: 360
CameraHeadingMode: 'auto'
CameraHeadingMode_I: 'auto'
CameraHeading_I: 360
CameraHeightMode: 'auto'
CameraHeightMode_I: 'auto'
CameraIsEnabled: 1
CameraListeners: [1×3 event.listener]
CameraOrientation: [0 -90 360]
CameraOrientationMode: 'auto'
CameraOrientation_I: [0 -90 360]
CameraPitch: -90
CameraPitchMode: 'auto'
CameraPitchMode_I: 'auto'
CameraPitch_I: -90
CameraPosition: [35.1576 -82.5000 1.7190e+07]
CameraPosition2DMode: 'auto'
CameraPosition2DMode_I: 'auto'
CameraPositionMode: 'auto'
CameraPosition_I: [35.1576 -82.5000 1.7190e+07]
CameraRoll: 0
CameraRollMode: 'auto'
CameraRollMode_I: 'auto'
CameraRoll_I: 0
ChildGraphicsID: 1
ChildGraphicsID_I: 1
Children: [0×0 GraphicsPlaceholder]
ChildrenMode: 'auto'
Children_I: [0×0 GraphicsPlaceholder]
CleanListener: []
ColorOrder: [7×3 double]
ColorOrderMode: 'auto'
ColorOrder_I: [7×3 double]
ColorSpace: [1×1 MapColorSpace]
ColorSpaceMode: 'auto'
ColorSpace_I: [1×1 MapColorSpace]
Copyable: 1
DefaultCameraPosition: [0 0 15000000]
DefaultPropMap_Internal: [0×0 struct]
Description: ''
DescriptionMode: 'auto'
Description_I: ''
ErrorCallback: ''
ErrorCallbackMode: 'auto'
ErrorCallback_I: ''
GlobeOptions: [1×1 globe.internal.GlobeOptions]
GlobeViewer: [1×1 globe.internal.GlobeViewer]
HTMLController: [1×1 HTML]
HandleVisibility: 'on'
HandleVisibilityMode: 'auto'
HandleVisibility_I: 'on'
Initialized: 1
Internal: 0
MaxHeight: 1800
MaxWidth: 2880
NextPlot: 'add'
NextPlotMode: 'manual'
NextPlot_I: 'add'
NextSeriesIndex: 1
NextSeriesIndexMode: 'manual'
NextSeriesIndex_I: 1
NodeChildren: []
NodeParent: [1×1 ScribeLayer]
Parent: [1×1 Figure]
ParentHasChanged: 0
ParentListener: [0×0 event.proplistener]
ParentMode: 'manual'
Parent_I: [1×1 Figure]
Position: [0 0 1 1]
PositionInPixels: [1 1 800 600]
PositionMode: 'auto'
Position_I: [0 0 1 1]
PostUpdateSource: [1×1 HTMLCanvas]
Serializable: on
SerializableApplicationData: [1×1 struct]
SerializableChildren: [0×0 GraphicsPlaceholder]
SerializableMode: 'auto'
SerializableUserData: []
Serializable_I: on
SourceObjectListener: [1×1 event.listener]
Tag: ''
TagMode: 'auto'
Tag_I: ''
Terrain: 'none'
TerrainMode: 'manual'
Terrain_I: "none"
TransformForPrintFcn: ''
TransformForPrintFcnImplicitInvoke: on
TransformForPrintFcnImplicitInvokeMode: 'auto'
TransformForPrintFcnImplicitInvoke_I: on
TransformForPrintFcnMode: 'auto'
TransformForPrintFcn_I: ''
Type: 'globe'
Units: 'normalized'
UnitsMode: 'auto'
Units_I: 'normalized'
UserData: []
ViewMode: 'auto'
ViewRequiresUpdate: 0
Visible: on
VisibleMode: 'auto'
Visible_I: on
No public property 'Viewer' for class 'trackingGlobeViewer'.
Error in Calc (line 72)
orderfields(struct(viewer.Viewer))
The above comment is the output of
orderfields(struct(viewer.Globe))
orderfields(struct(viewer.Viewer))
HTMLController: [1×1 HTML]
PostUpdateSource: [1×1 HTMLCanvas]
Hmmm... I am not certain that the Globe display involves an axes at all. It might, buried in some property we did not yet examine, but those HTML controller parts leave me wondering about the technology being used to implement this feature.
It is possible that this might be implemented in HTML or some web development framework. You don't think there is any other way to create an alert on the viewer itself?
I do not know; I would need to poke around the internals more, but I do not have that toolbox.
Perhaps it is time to consider using annotation . Annotations live in a transparent graphics pane above all of the other panes (so they should always be on top.) Because they do not live inside axes, the position coordinates for annotation default to being normalized relative to the figure . You can change the units, but you cannot change the units to data coordinates

Sign in to comment.

Categories

Asked:

on 23 Jan 2023

Commented:

on 2 Feb 2023

Community Treasure Hunt

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

Start Hunting!