How to save plot with its colourbar as .fig in Matlab GUI - matlab

I have a button which will produce plot along with its color bar by clicking on it. The button relates to certain function called zzpcolor. Inside zzpcolor, I use pcolor syntax to produce shake map.
Inside the callback function, I use hold on to hold the figure generated by zzpcolor. Then I add another plot to the same axis. This is part of the script within the push botton callback.
axes(handles.axes1);
axes1.Position=[0.1300 0.1100 0.7750 0.8150];
[X,Y,Z]=plotpcolor(fnamedat);
hold on
zzpcolor(X,Y,Z);
shading flat
LimitPlot
hold on
plot_google_map
hold on
scatter(datageo(:,1),datageo(:,2),'MarkerFaceColor',[1 0 0])
hold off
The syntax worked just fine. I use this syntax to save the plot as jpg in another callback function.
newfig1 = figure('Visible','off');
copyobj(handles.axes1, newfig1);
[filename,pathname]= uiputfile('*.jpg','Save as');
hold on
wmmicolorbarsetting;
saveas(newfig1,[pathname,filename],'jpg');
it works just fine. But when I try to save it as .fig using similar syntax like this,
newfig1 = figure('Visible','off');
copyobj(handles.axes1, newfig1);
[filename,pathname]= uiputfile('*.fig','Save as');
hold on
wmmicolorbarsetting;
saveas(newfig1,[pathname,filename],'fig');
the .fig file contains nothing. Why?

The .fig file does contain something. You set the figure Visible property to 'off' so the figure doesn't actually show up when you create the figure or when you load the figure from the file.
You can verify this by loading the .fig file with hgload and setting the Visible property to 'on'.
fig = hgload([pathname, filename]);
set(fig, 'Visible', 'on')
You can also look at the produced .fig file and ensure that it is non-empty.
You can fix this by setting Visible to 'on' prior to saving.
A note on figure visibility: Setting Visible to 'off' is useful for saving a figure as a format other than .fig (png, jpeg, etc.) because you can create an image without worrying about a bunch of figures showing up as your script runs. In these cases, no user interaction is required. As you've found out, if you actually need to see/interact with figures, Visible should be 'on' to be useful.

Related

Trouble opening .fig files in axes

I am creating a GUI in Matlab's Guide which should display a video and a plot saved in a .fig file. I am currently trying to open the plot in an axes element and while I know axes cannot be a container, the possibility of saving the plot in a another object and feeding that object to axes seems like a solution, but I don't know how to do that due to limited Matlab knowledge. Here is the only code I have for the button at the moment which allows me to open a file from my local directory.
% --- Executes on button press in pushbutton2.
function pushbutton2_Callback(hObject, eventdata, handles)
axes(handles.axes1);
[file,path] = uigetfile('*.fig');
[file,path] = uigetfile('*.fig'); only gets the path and name of the file that was selected, it doesn't load the file. To load the file you want to use,
hfig = openfig(fullfile(path,file));
However, since you don't really want to see the figure you most likely want to use the optional input
hfig = openfig(fullfile(path,file),'invisible');
to load the figure but make it invisible.
Then you'll need to move the image from the axes in hfig to the axes in your UI. This can be achieved in multiple ways, one of which is the use of copyobj.

How to make an axes current which is inside a figure created by GUIDE?

I created a bank figure using GUIDE and put an axes object inside it and saved the figure. Now I want to load the figure and set its axes as current axes object. This is my code:
close all; clear all; clc;
fh = openfig('test.fig');
ah = findobj(fh, 'tag', 'axes1');
figure(fh);
axes(ah);
plot(rand(10, 1));
But plot creates a new figure and plots in it! Am I missing something?
I know that I can solve it with plot(ah, ...), but I want to make gca to return this new axes. I have a lot of plotting codes that I want to be drawn in this new axes.
By default, HandleVisibility of GUIDE figures is set such that they aren't automatically detected. For example if you load the figure and then call gcf, you'll also create a new figure.
To have the plot be placed within the axes, you can specify the axes explicitly as the parent of the plot command.
plot(rand(10, 1), 'Parent', ah)
Alternately, you could specify that the HandleVisibility of the figure is 'on'. And then plot will be able to find it. This could be done by either setting the value of HandleVisibility using the property editor in GUIDE or calling the set function:
set(fh, 'HandleVisibility', 'on')
I recommend the first option as explicitly specifying the parent axes is always better than implicit.

Matlab openfig to existing figure

When in Matlab I use openfig(filename); to open a saved figure, it always opens a new window. All the 'reuse' argument does is not load the file when it appears to already be open. However, I wish to open the file into a given figure, and just overwrite its contents. Is there a way to pass a figure handle to openfig, or is there another function that would accomplish this?
So in code, what I would like to do is something along the following lines:
f = figure;
openfig(filename, 'Figure',f);
and then the figure would be displayed in figure f rather than having opened a second figure window.
I think you can arrange something close to what you want with the copyobj function. Here is a try with a docked figure:
% --- Create sample figure
h = figure;
ezplot('sin(x)');
set(gcf, 'Windowstyle', 'docked');
pause
% --- Replace the axes
clf
g = openfig('test.fig', 'invisible');
copyobj(get(g, 'CurrentAxes'), h);
delete(g);
Which gives me a smooth replacement of the axes, without flickering of the figure.
However, I don't know how this would behave with a fullscreen figure, it surely depends on the method you choose. Check also the doc of copyobj in detail, it's not copying everything so you may want to use the legacy option.

Display "imshow" images in a GUI using GUIDE

I have a piece of code that is 300 lines long. There is 3 different instances of imshow throughout the code that displays figures as the code is run..
The GUI I am creating will be very simple. Currently I have a push button that initiates the m file.
I am trying to get the images to be displayed within the GUI that I am creating and not in separate Figure windows.
I have being looking at tutorials online but cant get a quick fix for my problem, they all get a bit convoluted and I cant figure out what exactly to do.
I have 3 axis inserted onto the GUI, In the "view callbacks" for each axis I can createfcn, deletefcn and buttonDownFcn. When I createFcn it gives me a hint to "place code in OpeningFcn to populate axes1" in the auto generated code.
I have tried to do this but I am not able to find the correct place to write the code.
Can somebody tell me if I am going in the correct direction or if I have it wrong.
Thanks
In order to display these images, you need to declare the parent in imshow. The parent is what you want to act as the canvas for your image, and in your case will be an axes.
I created a very simple gui with three axes and a push button. MATLAB named my axes axes1, axes2 and axes3. Guide saves the handles to these axes so that you can interact with them throughout your gui code. For example, you mentioned the opening function... here is mine with a call to imshow (the only lines I added were the last three ones):
% --- Executes just before myGUI is made visible.
function myGUI_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for myGUI
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes myGUI wait for user response (see UIRESUME)
% uiwait(handles.figure1);
imshow('myImage1.png', 'Parent', handles.axes1)
imshow('myImage2.png', 'Parent', handles.axes2)
imshow('myImage3.png', 'Parent', handles.axes3)
Notice that I can grab the handles of my axes and then declare them to be the parents for the results of my imshow call.
If you're not sure what the names of your handles are, you can check in the GUI editor by right clicking, looking at the property inspector, and the tag property.
If you want to perform a similar operation for when you click on your pushbutton, right click on the button in the editor, and click on View Callbacks -> Callback, and you can add your imshow code there.
Good luck.
If I understand correctly you just want your images to appear in the axes instead of a figure. Try setting the focus to the axes itself before showing the image.
axes(1);%you may need to change the one to your axes handle.
imagesc(imageToBeDisplayed);
axes(2);
imagesc(secondImage);
axes(3);
imagesc(thirdImage);
This way before you call imagesc you make sure your program knows where to send the image. Otherwise it may just create a figure.

Matlab image display in specific old figures

Take an example, I have 2 a sequences of left and right images: left01, right01, left02, right02, etc. How can I display those on only two figures: left and right. Each loop, these 2 figures will be updated with leftxx and rightxx.
"Hold on" will only hold the current figure. Creating figures with figure('Name', 'Left') will not do the trick, as multiple "Left" figures will be created. Yet imshow() does not let me specify the figure to display based on its name.
What I want is something similar to OpenCV, which let you choose which figure (already opened) to display
cvNamedWindow("Left");
cvShowImage("Left", myLeftImg);
"Left" figure will be updated with new img without creating new figure.
Thanks a lot.
Ken.
You need to save a handle on the axes-object within the figure and you need to tell the image-function to precisely which axes you want it to draw.
Try something along the lines of:
figure, h_r = axes;
figure, h_l = axes;
for n=1:whatever
image(right_bitmap, 'Parent', h_r, ...);
image(left_bitmap, 'Parent', h_l, ...);
drawnow;
end;
Update: image expects the handle as property 'Parent' rather than as first parameter.