copy graphic to Excel

How can I take the code below to just copy the graphic on axes component (axes1) to clipboard. I then have code to paste it to excel. It currently copies all of my matlab screen.
axes(handles.axes1)
Z=peaks
surf(Z)
print -dmeta; %.................Copying to clipboard

回答(2 个)

screencapture('handle',ax, 'filename', fn); % save the graph in file fn
exlSheet.Shapes.AddPicture(fn,0,1,...
20,... % distance from left of sheet
20,... % distance from top of sheet
600,... % width
400); % height
Note that you will need to have opened an actxserver connection to MATLAB. In the above, ax is the handle to your axes, fn is the file where your image is saved, and exlSheet is an Excel Sheet object.
EDIT: Here is some sample actxserve code. I have had a chance to test this and it works for me. Refer to http://www.mathworks.com/help/techdoc/ref/actxserver.html if needed.
x = 0:0.1:10;
y = sin(x);
f = figure;
ax = axes('parent',f);
plot(ax,x,y);
fn = fullfile(pwd,'myplot.bmp');
screencapture('handle',ax, 'filename', fn);
e = actxserver('Excel.application');
eW = e.Workbooks;
eF = eW.Add; % start a new file; use Open method for existing files
eS = eF.ActiveSheet;
e.Visible = 1; % Excel window won't show up by default
eS.Shapes.AddPicture(fn,0,1,...
20,... % distance from left of sheet
20,... % distance from top of sheet
400,... % width
300); % height

17 个评论

Thanks for the link. When I enter the handle ax as axes1 e.g
screencapture('handle',axes1, '"filename', 'test2.xls'); % save the graph in file fn
I get an error message:
??? Undefined function or variable 'axes1'.
From your original post, it looks like your axes handle is stored in a handles structure. So you'll need to use:
screencapture('handle',handles.axes1,...);
I keep getting this error:
No value specified for property 'C: est2_plot.xls'
Here is my code:
function pushbutton3_Callback(hObject, eventdata, handles)
fn='C:\test2_plot.xls';
screencapture('handle',handles.axes1, '"filename',fn ); % save the graph in file fn
%.............excel COM object............................................................................
Excel = actxserver ('Excel.Application');
Excel.Visible = 1;
Excel.Shapes.AddPicture(fn,0,1,...
20,... % distance from left of sheet
20,... % distance from top of sheet
600,... % width
400); % height
if ~exist(fn,'file')
ExcelWorkbook=Excel.Workbooks.Add;
ExcelWorkbook.SaveAs(fn);
ExcelWorkbook.Close(false);
end
invoke(Excel.Workbooks,'Open',fn); %Open the file
ActiveSheet = Excel.ActiveSheet;
ActiveSheetRange = get(ActiveSheet,'Range',Range);
ActiveSheetRange.Select;
ActiveSheetRange.PasteSpecial; %.................Pasting the figure to the selected location
It looks like you don't quite understand how actxserver works. I recommend reading <http://www.mathworks.com/help/techdoc/ref/actxserver.html> thoroughly. In the code I posted before, fn was the filename of the image, not of the Excel spreadsheet. (That is, it was the filename where you wanted to save the image. The exlSheet.AddPicture call was importing the image into Excel.) The exlSheet variable is an Excel Sheet object, not the Excel Application object that you have used. I'll edit my answer (I don't think I can use code markup in the comments) with some sample code.
Thanks Andy. Just one comment, I dont want or need to save the graphic on the axes1 component to a file. Are you saying , I have to in order to get this to work?
Thanks
Also. This seems like a lot more code than the original post:
axes(handles.axes1)
Z=peaks
surf(Z)
print -dmeta;
Is the absolutely no way to use this print -dmeta with an axes component rather than a figure.
It still seems to be struggling with the axes1 handle:
??? Error using ==> screencapture>processArgs at 188
Error setting ScreenCapture property :
Error using ==> screencapture>processArgs at 156
No value specified for property 'myplot.bmp'
Well,
1. This isn't so much code, it can be condensed, and it is much more powerful and flexible. You don't need to store the Workbooks object, the file eF, and the Sheet eS if you won't access them, so the code could be simplified to:
e = actxserver('Excel.application');
eS = e.Workbooks.Open('yourfile.xls').ActiveSheet.AddPicture(fn,0,1,...)
e.Visible=1;
Via actxserver, you also have complete programmatic control over Excel.
2. I'm not very familiar with the -dmeta option, but I would generally recommend against programmatically writing to the clipboard and then programmatically pulling from the clipboard as a method of copy/paste. What if this code runs, and then something else copies other data to the clipboard before your pasting code runs? That said, you could try (note: I have not tried this):
print(handles.axes1,'-dmeta');
Alright, I just tried out the print command, and it only accepts figure handles (not axes handles). Your figure handle is probably handles.f (but if not, adjust the following):
print(handles.f, '-dmeta');
I dont actually have a figure as Im plotting straight to axes1 in a GUI. Have i missed something?
Thanks for your patience!
Did you create this GUI, either in GUIDE or programmatically?
Yes in Guide.
Sorry for the delay. If you created the GUI with GUIDE and did not change the default handles, then handles.figure1 is the handle to the figure itself. You may not have been aware of it, but you do actually have access to all of the handles of the controls of your GUIDE GUI.
Hi Andy, no probs over the delay, Im grateful for your help. Thats interesting about the existence of figure 1. Is there a way to view all the figure handles so I know exactly what exists?
Thanks
I'm not quite sure what you mean. Do you have multiple figures? If so, you can type at the command line:
figurelist = findall(0, 'type', 'figure');
If you mean you want to see all of the handles to controls in your GUI figure, then you only need to print the handles structure. (Alternatively, if you open your GUI in GUIDE, you can right click on a control, open the property inspector, and look at its Tag property.)
Im, still confused over the figure1 issue. On my GUI created in GUIDE, I drag an axes component and leave its tag as default - axes1. I then plot to axes 1 by :
axes(handles.axes1)
Z=peaks;
surf(Z);
I do not create a figure.
So writing hf=handles.figure1 and then print(handles.figure1, '-dmeta');
just copys the whole GUI to clipboard, not the axes 1 component that I am after. Is it worth sharing my files?
Thanks
That's correct. It's a documented limitation of the print function that it cannot take as an argument, for example, just the axes handle. Yair Altman's screencapture utility that I linked to before CAN capture only the axes without copying the whole figure. I'm not at MATLAB right now, so I can't be certain, but I don't think there is a way for the screencapture utility to write to the system clipboard. That's why I suggested writing to a file and then importing the file into Excel. I really think this is the best solution, but when I'm next using MATLAB I can try to think of something that doesn't produce the intermediate file.

请先登录,再进行评论。

hf = figure;
surf(peaks)
print('-dmeta',hf)

6 个评论

Im confused. I don't have a figure as Im using GUIDE with an axes component called axes1.
you do have a figure, this
hf=handles.figure1
whats figure1?
The parent of axes1.
hf = get(handles.axes1,'parent');
will find it for you, if it's not called figure1.
It still copies the whole GUI and not just the graphic in the axes component.
Yes, that has been pointed out to you before. I have updated the code in my answer with tested code which works correctly and copies only the axes.

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Creating, Deleting, and Querying Graphics Objects 的更多信息

标签

提问:

2011-5-13

Community Treasure Hunt

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

Start Hunting!

Translated by