Plot appearing in new figure?

15 views (last 30 days)
Ali Shakeri
Ali Shakeri on 31 Oct 2020
Commented: Ali Shakeri on 1 Nov 2020
I'm trying to plot a 3D figure(surf plot) inside a figure that I have already created but for some reason my new plot is created in a separate figure. The code consist of 2 scripts which I will be posting. The first script initializes the act frame I want to draw in and its callback (from the slider) draws my cylinder which for some reason appears inside a new frame leading to this mess:
Main script that creates the main figure I want to draw in.
%%
clf;
clear;
close all;
clc;
load('myHeatMap.mat','myHeatMap');
filename = ('C:\Users\Ali\Desktop\Documents\DataVis\Projekt\data\day\filenames.txt');
%This line simply gives us a table of all filenames in this file.
T = readtable(filename);
tsize = size(T);
tsize2 = size(T, 1);
filename = strcat('\Users\Ali\Desktop\Documents\DataVis\Projekt\data\day\', string(T{1,1}));
map100 = getCylinderHeatMap(filename);
%Figure/parent container (uifigure) properties%
App = uifigure('Scrollable','on','Name','Heatmap Plots','NumberTitle','off');
App_Width = 1000; App_Height = 500;
App.Position = [0 0 App_Width App_Height];
%Slider label (uilabel) properties%
Slider_Label = uilabel('Parent',App);
Slider_Label.Text = "Cylinder Number";
Slider_Label.Position = [25 20 200 100];
%Slider (uislider) properties%
Slider = uislider('Parent',App);
Slider.Limits = [1 1000];
Slider.Value = 1;
Slider_Width = App_Width - 500;
Margin = (App_Width - Slider_Width)/2;
Slider.Position = [Margin 50 Slider_Width 3];
Slider.MajorTicks = (1:100:1000);
Slider.FontSize = 6;
Red = 87; Green = 207; Blue = 220;
Slider.FontColor = [Red/255 Green/255 Blue/255];
%Plot (uiaxes) properties%
Heatmap_Cylinder_Plot = uiaxes('Parent',App);
Heatmap_Cylinder_Plot_X_Position = 100;
Heatmap_Cylinder_Plot_Y_Position = 100;
Heatmap_Cylinder_Plot_Height = 350;
Heatmap_Cylinder_Plot_Width = 400;
Heatmap_Cylinder_Plot.Position = [Heatmap_Cylinder_Plot_X_Position Heatmap_Cylinder_Plot_Y_Position Heatmap_Cylinder_Plot_Width Heatmap_Cylinder_Plot_Height];
Heatmap_Cylinder_Plot.GridColor = [0.15 0.15 0.15];
Heatmap_Cylinder_Plot.XGrid = 'on';
Heatmap_Cylinder_Plot.YGrid = 'on';
Heatmap_Cylinder_Plot.ZGrid = 'on';
%Image (uiimage) properties%
Heatmap_Image = uiimage('Parent',App);
Heatmap_X_Position = (App_Width/2) + 50;
Heatmap_Y_Position = 80;
Heatmap_Height = 350;
Heatmap_Width = 400;
Heatmap_Image.Position = [Heatmap_X_Position Heatmap_Y_Position Heatmap_Height Heatmap_Width];
%Callback function as the slider is moved%
Slider.ValueChangedFcn = @(Slider,event) Snap_Slider(Slider,Slider_Label,Heatmap_Cylinder_Plot,Heatmap_Image,T,...
myHeatMap);
%%
%Callback function definition%
function [] = Snap_Slider(Slider,Slider_Label,Heatmap_Cylinder_Plot,Heatmap_Image,T,myHeatMap)
Slider.Value = round(Slider.Value);
filename = strcat('\Users\Ali\Desktop\Documents\DataVis\Projekt\data\day\', string(T{Slider.Value,1}));
map100 = getCylinderHeatMap(filename);
splitFileName = strsplit(string(T{Slider.Value,1}),'.');
Slider_Label.Text = "Time Stamp: " + splitFileName{1,1};
%Put plotting code here%
plot(Heatmap_Cylinder_Plot,createSurfCylinder(map100));
%Put image plotting code here%
Heatmap_Image.ImageSource = "";
colormap(myHeatMap);
end
%%
Script for drawing actual Cylinder.
function cylinder = createSurfCylinder(matrix)
%Load heat map.
load('myHeatMap.mat','myHeatMap');
%%
%Cylinder creation
Sample_Range = 255 - 0;
Temperature_Range = 450 - 50;
Multiplier = Temperature_Range/Sample_Range;
map100 = matrix.*Multiplier + 50;
%Setting up the figure%
Radius = 1.5;
Number_Of_Data_Points = 360;
theta = linspace(0,2*pi,Number_Of_Data_Points);
%The xy values according to radius and number of points%
Z_Circle = Radius*cos(theta);
Y_Circle = Radius*sin(theta);
map100 = rot90(map100);
Height = 512;
Z_Circle = repmat(Z_Circle,Height,1);
Y_Circle = repmat(Y_Circle,Height,1);
X_Length = (1:512)';
X_Length = repmat(X_Length,1,Number_Of_Data_Points);
figure('Position', [10 10 800 800])
clf;
close;
cyl = surf(X_Length,Y_Circle,Z_Circle,'Cdata',map100);
title("3D Cylinder Heatmap Plot");
zlabel("Z-Position");
ylabel("Y-Position");
xlabel("Length(Cm)");
set(gca,'Ydir','reverse')
colormap(myHeatMap);
colorbar;
shading interp
Maximum_Value = 450;
Minimum_Value = 50;
caxis([Minimum_Value Maximum_Value]);
%Show the image in the subplot and add custome color coding to it.
% subplot(1,3,3); imshow(rot90(map100));
% colormap(myHeatMap);
% caxis([Minimum_Value Maximum_Value]);
cylinder = cyl;
%%
end
The getCylinderHeatMap script is of little importance it just returns a matrix of data used to plot the cylinder.
Any one that knows how to make my cylinder appear in my original Uiframe? Any help would be much appreciated.

Accepted Answer

Adam Danz
Adam Danz on 31 Oct 2020
Edited: Adam Danz on 31 Oct 2020
The Slider.ValueChangedFcn function is invoked by the slider and calls createSurfCylinder(). That's where the additional figure is being created. You have to include the axis handles from your app in all of the lines commented below.
function cylinder = createSurfCylinder(matrix)
% [ SKIPPING STUFF ]
figure('Position', [10 10 800 800]) %
clf; % What's up with this??
close; %
cyl = surf(X_Length,Y_Circle,Z_Circle,'Cdata',map100); %
title("3D Cylinder Heatmap Plot"); %
zlabel("Z-Position"); % ALL OF THIS
ylabel("Y-Position"); % STUFF NEEDS
xlabel("Length(Cm)"); % TO INCLUDE
set(gca,'Ydir','reverse') % AXIS HANDLES!
colormap(myHeatMap); %
colorbar; %
shading interp %
% [ SKIPPING STUFF ]
caxis([Minimum_Value Maximum_Value]); %
% [ SKIPPING STUFF ]
end
Also, and more importantly, it looks like every time the slider is changed the figure is recreated from scratch. Ouch! That's like building a new house every time you need to clean the floors.
Instead, the slider should update the plot rather that recreate it. Use the cyl output to simply update the surface data.
  3 Comments
Adam Danz
Adam Danz on 31 Oct 2020
There's a couple ways to go about this. A relatively easy method is to use a persistent variable that stores the surf object. On the first time the function is called, the surf object (cyl) will be empty and/or invalid and will be created. Otherwise the surf object will just be updated.
function cylinder = createSurfCylinder(matrix)
persistent cyl
if isempty(cyl) && isvalid(cyl)
%Load heat map.
load('myHeatMap.mat','myHeatMap');
% [ SKIPPING STUFF ]
cyl = surf(X_Length,Y_Circle,Z_Circle,'Cdata',map100);
% [ SKIPPING STUFF ]
else
% [ INSERT CODE TO UPDATE "cyl" ]
end
Ali Shakeri
Ali Shakeri on 1 Nov 2020
Thank you, i was wondering how to ddo the handle stuff tho i already fixed this :D.
Still thank you soo much.

Sign in to comment.

More Answers (0)

Categories

Find more on Data Distribution Plots in Help Center and File Exchange

Products


Release

R2020b

Community Treasure Hunt

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

Start Hunting!