Hello. I am wanting top copy several plots from my gui. One plot is on a uipanel and the other is a graph on an axes component. I have tried the axes component first using :
currAxes = handles.axes1
newFig = figure('visible','off');
newHandle = copyobj(currAxes,newFig);
print(newFig,'-dmeta');
delete(newFig);
It sort of works. The issues are: 1: It only copies one of the yaxis (the plot on axes1 is a plot with two yaxis, using plotyy). 2: It copies with a large box around it.
The attached image shows the result of the copy, and the actual graph I want copied.
Am I using the correct method? Thanks Jason

1 comentario

muhammad zulhelmy
muhammad zulhelmy el 5 de Mzo. de 2017
how can i copy data from axes2, then display to axes3 ??

Iniciar sesión para comentar.

 Respuesta aceptada

Orion
Orion el 3 de Nov. de 2014

0 votos

if you're using GUIDE, don't forget to get and restore the handles structure with guidata
function Your_plot_Pushbutton(hObject, eventdata, handles)
% code,code,code
[AX,H1,H2] = plotyy(A,B,A,C,'plot');
handles.yyaxis=AX;
% save the changes to the structure
guidata(hObject,handles)
and then you can retrieve it in the copy function
function Your_copy_Pushbutton(hObject, eventdata, handles)
hAX=handles.yyaxis;

14 comentarios

Jason
Jason el 3 de Nov. de 2014
Editada: Jason el 3 de Nov. de 2014
Hi, Im sorry to keep bugging you over this - im still getting errors.
Its a shame there isn't a copycanvas command as in c++ where you can give vectors of box you want to copy on the screen.
heres my copy code:
hAX=handles.yyaxis;
newFig = figure('visible','on');
% copy the axes in the 2nd figure
hcop = copyobj(hAx,newFig);
axes(hcop(2)); % to put the second axe (transparent) in first plan
% resize if needed the dimensions of the axes to fill screen
% with the value you want (Normalized)
set(findall(newFig,'Type','Axes'),'Position',[ 0.100 0.1100 0.8 0.8150]);
% metacopy
print(newFig,'-dmeta');
and the error
Undefined function or variable 'hAx'.
Error in Montage>pushbutton21_Callback (line 1725)
hcop = copyobj(hAx,newFig);
If I view hax, I get: hAX =
1x2 Axes array:
Axes Axes
Undefined function or variable 'hAx'.
Error in Montage>pushbutton21_Callback (line 1725) hcop = copyobj(hAx,newFig);
does this indicate that hAX is empty.
Im actually plotting in a loop, outside the loop I assign AX to handles.yyaxis
Jason
Jason el 4 de Nov. de 2014
Well spotted, it was the end of the day...tired!!
It now works BUT I can't get the same aspect ratio as the original graph. If I attempt to reduce the height by:
set(findall(newFig,'Type','Axes'),'Position',[ 0.100 0.1100 0.8 0.3]);
its the correct shape, but now are larger area is copied.
If, I put back set(findall(newFig,'Type','Axes'),'Position',[ 0.100 0.1100 0.8 0.8150]);
and change the size of the figure on creation so it itself is rectangular and matches the real aspect ratio
newFig = figure('Position',[600 600 800 100],'visible','on');
it still copes an almost square graph, when I paste it in ppt or word and try and squash it, it looks all wrong.
Orion
Orion el 4 de Nov. de 2014
Editada: Orion el 4 de Nov. de 2014
If you know the size ( let say in pixel) of the original axe : PosOrigAxe.
use these dimensions to create the new figure.
newFig = figure('Position',[10 10 PosOrigAxe(3:4)],'visible','on');
then for the copies of the axe, which are in Normalized units, make them full the figure.
set(findall(newFig,'Type','Axes'),'Position',[0 0 1 1]);
Jason
Jason el 4 de Nov. de 2014
so PosOrigAxe(3:4) would be replace with
handles.axes1(3:4) in my case??
Orion
Orion el 4 de Nov. de 2014
Editada: Orion el 4 de Nov. de 2014
I'm more thinking of something like :
OrigUnits = get(handles.axes1,'Units'); % save the orginial unit used
set(handles.axes1,'Units','Pixels'); % change it to pixel
PosOrigAxe = get(handles.axes1,'Position'); % get the position
set(handles.axes1,'Units',OrigUnits); % restore the unit
Now, the information that you're interested in : PosOrigAxe(3) (width) and PosOrigAxe(4) (height). these are the dimensions, in pixels, of your original axe. Use it to create the figure.
another way to write it :
newFig = figure('Position',[10 10 PosOrigAxe(3) PosOrigAxe(4)],'visible','on');
the values 10 and 10 are not important, it's just to specify the origin of the figure, but you don't need it, because, it will be invisible, so you can specify any other value.
Jason
Jason el 4 de Nov. de 2014
Ok I see now. This works, but now when I paste it, it loose its aspect ratio, again resizing then squashes the text
Orion
Orion el 4 de Nov. de 2014
let's get done with this :
full demo (works with my machine/screen). I add the variable MyRatioToReDraw which allows to keep the ratio Width/height of the axe, but you can make the new figure bigger or smaller, according the need of the metacopy.
clear all
close all
x = 0:0.01:20;
y1 = 200*exp(-0.05*x).*sin(x);
y2 = 0.8*exp(-0.5*x).*sin(10*x);
figure % new figure
[hAx,hLine1,hLine2] = plotyy(x,y1,x,y2);
set(gcf,'Position',[240 248 981 250]);
OrigUnits = get(hAx(1),'Units'); % save the orginial unit used
set(hAx(1),'Units','Pixels'); % change it to pixel
PosOrigAxe = get(hAx(1),'Position'); % get the position
set(hAx(1),'Units',OrigUnits); % restore the unit
MyRatioToReDraw = 0.5; % to make the copy 2 times bigger, or any other value. find the one who suits you
newFig = figure('visible','on','Position',[50 50 MyRatioToReDraw*PosOrigAxe(3:4)]);
%%copy the axes in the 2nd figure
hcop = copyobj(hAx,newFig);
axes(hcop(2)); % to put the second axe (transparent) in first plan
%%resize if needed the dimensions of the axes to almost the fill screen
% with the value you want (Normalized)
set(findall(newFig,'Type','Axes'),'Position',[ 0.1 0.1 .8 .8 ]);
%%metacopy
print(newFig,'-dmeta');
Jason
Jason el 4 de Nov. de 2014
when you do the paste, does it remain with the same width to height ratio?
Orion
Orion el 4 de Nov. de 2014
I paste it in Paint and get the exact copy of my newfigure.
See the attached image.
In the top the result of the metacopy in paint. just below, the newfigure, created by the example with MyRatioToReDraw = 1.2
Jason
Jason el 4 de Nov. de 2014
Editada: Jason el 4 de Nov. de 2014
Thats very strange. when I keep the newFig open, it does indeed duplicate as required
But when I do a paste into either paint or ppt, it stretches vertically, but not the text (so I can't then compress it back)
I have noticed, if I use the edit menu in figure 1 and do a copy, then IT DOES paste properly into paint and powerpoint
Orion
Orion el 4 de Nov. de 2014
If you do the paste with a random figure and plot.
fig = figure('Position',[240 148 981 150]);
plot(sin(0:0.01:10));
print(fig,'-dmeta');
Is the paste also stretched ?
If so, then the problem is inside the print function, and i don't know what's the problem will be.
Otherwise, the problem is within the figure you created, and you'll have to check the differents properties to find which one is bugging you.
With the example I posted, is the copy stretched ?
Jason
Jason el 4 de Nov. de 2014
Yes, it is also stretched. I think you have kindly spent too much of your time helping me and I am very grateful. Im going to try and search if there is away to evoke the paste from edit menu as that seems to work, but it means havign to view the figure.
Thankyou again for your kind help. Jason
Orion
Orion el 4 de Nov. de 2014
So, gook luck.
And I get one last Idea.
You can try the same callback as in the edit menu of the figure, which seem to work on your machine. It works for me.
Replace the call to print with editmenufcn.
%%metacopy
% print(newFig,'-dmeta');
editmenufcn(newFig,'EditCopyFigure')
Jason
Jason el 4 de Nov. de 2014
Perfect,thankyou again! Jason

Iniciar sesión para comentar.

Más respuestas (4)

Orion
Orion el 3 de Nov. de 2014

0 votos

Hi,
Actually, plotyy creates 2 superimposed axes objects (see the doc about the differents outputs arguments).
So you need to copy all the axes in the new fig.
with your code
currAxes = handles.axes1
newFig = figure('visible','off');
newHandle = copyobj(currAxes,newFig);
print(newFig,'-dmeta');
you are only copying one axe, so it's logical that you miss the second.
you may need to do something like:
AllAxes = findall(gcf,'Type','Axes') % get all the axes
newFig = figure('visible','off');
newHandle = copyobj(AllAxes,newFig); % copy all axes in the figure to print
print(newFig,'-dmeta');

1 comentario

Jason
Jason el 3 de Nov. de 2014
Editada: Jason el 3 de Nov. de 2014
Hi, thankyou for pointing out the behaviour of plotyy.
In your code, you are finding the handles of the type "Axes". The problem with my application is besides this graph, I also have about 5 other axes components that will obviously also be picked up. How do I limit your findall command to just handles.axes1?
This also explains why when I do a cla , only the one plot clears. How can I clear both plots?. Could I use the following but not use delete, instead cla?
delete(get(handles.axes2,'children'))
Thanks Jason

Iniciar sesión para comentar.

Orion
Orion el 3 de Nov. de 2014

0 votos

In the prototype of plotyy
[AX,H1,H2] = plotyy(...)
AX is a vector containing the handles of the 2 axes objects created by plotyy.
so when you stock your data, you could do
handles.axesplotyy_1 = AX(1);
handles.axesplotyy_2 = AX(2);
and then use these handles the way you need.
AxesToCopy = [handles.axesplotyy_1 handles.axesplotyy_2];
newFig = figure('visible','off');
newHandle = copyobj(AxesToCopy,newFig);
then do the same to delete/cla
delete([handles.axesplotyy_1 handles.axesplotyy_2]) % destroy both axes

1 comentario

Jason
Jason el 3 de Nov. de 2014
Hello. Its still not copying all the data, it now has the 2nd y axis labels and tickmarks. Its also still inside a much larger frame thats also being copied, as per original image at top of this thread?

Iniciar sesión para comentar.

Orion
Orion el 3 de Nov. de 2014
Editada: Orion el 3 de Nov. de 2014

0 votos

my bad, i went a little fast in my explanation.
So, with an example
x = 0:0.01:20;
y1 = 200*exp(-0.05*x).*sin(x);
y2 = 0.8*exp(-0.5*x).*sin(10*x);
figure % new figure
[hAx,hLine1,hLine2] = plotyy(x,y1,x,y2);
newFig = figure('visible','on');
% copy the axes in the 2nd figure
hcop = copyobj(hAx,newFig);
axes(hcop(2)); % to put the second axe (transparent) in first plan
% resize if needed the dimensions of the axes to fill screen
% with the value you want (Normalized)
set(findall(newFig,'Type','Axes'),'Position',[ 0.100 0.1100 0.8 0.8150]);
% metacopy
print(newFig,'-dmeta');

3 comentarios

Jason
Jason el 3 de Nov. de 2014
I actually do the plotting in one pushbutton callback, and then want to copy it with another, so should I save the hAx to the handles structure, use "userdata", or shoudl I use setappdata and then getappdata?
Thanks
Orion
Orion el 3 de Nov. de 2014
Editada: Orion el 3 de Nov. de 2014
it's really up to you, depending on your "coding style".
Personnaly, I like to use setappdata/getappdata, when manipulating handles between multiple figures.
use setappdata in the plot function
then getappdata in the copy function
Jason
Jason el 3 de Nov. de 2014
Editada: Jason el 3 de Nov. de 2014
hmmmm. I thought I knew how to use the handles structure to hold variables.
This is my plot:
[AX,H1,H2] = plotyy(A,B,A,C,'plot');
set to handles structure so can use outside this callback
handles.yyaxis=AX;
and to retrieve in a different button callback
hAX=handles.yyaxis;
and I get the error: Reference to non-existent field 'yyaxis'.
Error in Montage>pushbutton21_Callback (line 1719)
hAX=handles.yyaxis; %extract axis from handles structure

Iniciar sesión para comentar.

Orion
Orion el 3 de Nov. de 2014

0 votos

Matlab is clear,
Undefined function or variable 'hAx'.
when you do
hcop = copyobj(hAx,newFig);
you are using hAx, but you created the variable with hAX : X instead of x.
hourra for the end of the day.

Categorías

Más información sobre Creating, Deleting, and Querying Graphics Objects en Centro de ayuda y File Exchange.

Preguntada:

el 3 de Nov. de 2014

Comentada:

el 5 de Mzo. de 2017

Community Treasure Hunt

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

Start Hunting!

Translated by