Can MATLAB generate, save, and then load axes into a gui axes object dynamically?
Edited for clarity:
I have a GUI that controls a script that generates approximately 40 plots. I want to display any given plot in the GUI window on demand by selecting its number in a drop-down box. The problem is that the plots take a while to generate so I would rather make them once and then load them as needed into the axes object in the GUI. The plots each have different properties, labels, legends, etc..
I tried generating figures and then saving the开发者_如何学Cm and trying to load that into the axes object in the GUI and it did not work.
If I initially make the plots using the axes object in the GUI as the target axes I can't save the plot and the legends, etc..
Is this possible in MATLAB?
If I understand the question correctly, you have a GUI with axes and a callback to plot stuff into the axes. For some reason, e.g. because plotting takes a while, you want to be able to save a specific plot and have the ability to reload it.
The easiest way to deal with this issue is to not put an axes object into your GUI, but to use a two-window GUI, where one window has all the controls, and the other is the figure into which you plot stuff. This is advantageous for several reasons: Saving/loading becomes easy, you have access to the figure toolbar, and you can resize etc the figure as you wish (resizing GUIs is generally hairy). You can store the handle to the axes of the figure in the GUI handle structure via SETAPPDATA and access it via GETAPPDATA. Note that you'll want to put a small check at the beginning of your plotting callback, where you check whether the figure still exists using ISHANDLE on the axes handle, and open a new figure if the check returns false
.
If you really want to have an axes object in your GUI, the easiest is to just save the x and y data, as well as other properties of the plot that a user may be able to customize (whether the legend is on, or off, or the legend's position
property), so that you can regenerate it on the fly.
If, for some reason it is not sufficient to save just properties, you can generate a hidden figure, and use COPYOBJ to copy the axes and its children to that figure, which you then save. However, this is rather clumsy and might come with all kinds of surprising annoyances.
You need to know the handles of axes within the figure. Otherwise it will be difficult to change the axes properties if the figure contains a newer axes object, because gca will refer to the new axes.
The axes can be accessed post figure generation through the figure object because individual axes of a figure are children of the figure object. The following code snippet may help you.
close all
subplot(2,1,1)
subplot(2,1,2)
hAxes = get(gcf, 'Children')
get(hAxes(1)) %shows axes properties of one axes obj
get(hAxes(2)) %shows axes properties of the other
set(hAxes(1), 'YTickLabel', ['a';'b';'c';'d';'e';'f']) %set an axis property
I'm guessing a bit here, but it sounds like you want to create a GUI with an axes that displays different plots, legends, etc. based on which item of a drop-down menu is selected. If this is right, I'm guessing the problem you are having is that plotting a new set of data in the axes causes the old data to be replaced, leaving you to have to regenerate the entire plot anew every time you select a new menu item.
One way I would consider approaching this problem would be to make use of UIPANELs and the 'Visible'
property of graphics objects. You could create one panel per menu item, add an axes to each along with whatever data you wish to plot, then simply toggle the visibility of the panels using the SET command instead of replotting everything when a new menu item is selected. Here's an example:
hFigure = figure; %# Create a figure
hPanelA = uipanel('Parent',hFigure); %# Add panel A to the figure
hAxesA = axes('Parent',hPanelA); %# Add an axes to panel A
plot(hAxesA,1:10,rand(1,10),'r'); %# Plot a red line
text(5,0.5,'hello','Parent',hAxesA); %# Plot some text
legend(hAxesA,'red line'); %# Add a legend
hPanelB = uipanel('Parent',hFigure); %# Add panel B to the figure
hAxesB = axes('Parent',hPanelB); %# Add an axes to panel B
plot(hAxesB,1:10,rand(1,10),'b'); %# Plot a blue line
text(5,0.5,'world','Parent',hAxesB); %# Plot some text
legend(hAxesB,'blue line'); %# Add a legend
Now, you can make panel A visible and panel B invisible by doing the following:
set([hPanelA hPanelB],{'Visible'},{'on'; 'off'});
And you can do the reverse (hide panel A and show panel B) by doing this:
set([hPanelA hPanelB],{'Visible'},{'off'; 'on'});
You should notice that toggling between the two panels with their two separate axes is quick and smooth, which likely wouldn't be the case if you had to erase and replot data in a single set of axes every time you wanted to look at a new plot. Creating all the graphics objects you need when the GUI is created, then modifying the visibility (or other properties) as needed with the SET command makes for a more efficient GUI.
Also note that you can still modify object properties even when they are invisible, so (continuing from my example above) I could do something like this:
set([hPanelA hPanelB],{'Visible'},{'on'; 'off'}); %# Hide panel B
set(hPanelB,'BackgroundColor','b'); %# Change the color of panel B
set([hPanelA hPanelB],{'Visible'},{'off'; 'on'}); %# Show panel B
And now you should see that the background color of panel B is blue. If you also saved handles to your plotted lines and text, you could update them with new values before making them visible again.
精彩评论