Copy Figure Elements to System Clipboard

Hi,
I frequently use matlab on multiple adjacent computers running their own instances of matlab, and sometimes I want to share a trace or a title or an axis across figures in different computers.
I have third party software (search sharemouse or inputdirector for example) that enables clipboard sharing across multiple computers, so if there is any way that I can copy a figure element to the system clipboard and not just within the plot editing mode's internal version of the clipboard, i'll be good to go.
Perhaps a simpler problem that would be equally useful is if there is some way to copy an entire figure to the clipboard in a way that it can be pasted back into another instance of matlab, rather than as a bitmap for opening in word like the 'copy figure' option enables.
Thanks!

 Réponse acceptée

Jan
Jan le 19 Sep 2013
Modifié(e) : Jan le 5 Oct 2013
You can create a menu to copy the contents of a fig file as byte stream in the clipboard. Simply create a FIG file by hgsave, import the contents by fread and copy the data as string to the clibboard with a meaningful header:
[EDITED, code refreshed]
function FigClipboard(command, FigH)
% Copy & paste a figure through the clipboard
% Copy a figure: FigClipboard('copy', FigH)
% Open a new copy: FigClipboard('paste')
%
% License: Copy, modify, use like you want.
file = fullfile(tempdir, 'FigForClipboard.fig');
magic = '$FigToClipboard$';
switch command
case 'copy' %
if nargin == 1
FigH = gcf;
end
hgsave(FigH, file);
fid = fopen(file, 'r');
stream = fread(fid, Inf, 'uint8');
fclose(fid);
clipboard('copy', [magic, sprintf('%02x', stream)]);
delete(file);
case 'paste'
str = clipboard('paste');
if ischar(str) && strncmp(str, magic, length(magic))
fid = fopen(file, 'w');
if fid == 1
error('Cannot open file for writing: %s', file);
end
stream = sscanf(str(length(magic) + 1:end), '%2x');
fwrite(fid, stream, 'uint8');
fclose(fid);
openfig(file);
end
end
[/EDITED]
There must be a function which avoids the indirection over the hard disk. FIG files have the same format as MAT files and they contain a struct only. So it should be possible to re-create the figure directly from this struct instead from writing a file. But I do not find these methods directly and the additional speed is nice, but not a must-have.

5 commentaires

David
David le 24 Sep 2013
Hi Jan,
This seems like exactly what I want to do. My only problem- I don't want to have to run code to add a menu option every time a make a figure.
I can write a code that will use uimenu to add a menu option to a specific figure, but is there any way to make my menu always show up on any figure??
I know about startup.m, but I don't know if its possible to set a default option in root for every figure graphics object to come with a uimenu child.
Let me know if you have any ideas.
Thanks!
David
Jan
Jan le 25 Sep 2013
Modifié(e) : Jan le 25 Sep 2013
@David: Don't modify the default behavior of figures. If you have insert a bug or incompatibility with future Matlab versions, all dialogs and message boxes would be affected and potentially not appearing.
Better create a small wrapper for the figure command:
function H = myFigure(varargin)
FigH = figure(varargin);
uimenu(..., 'Callback', {@CopyToClipboard, FigH});
if nargout ~= 0
H = FigH;
end
function CopyToClipboard(MenuH, EventData, FigH)
...
Then only tiny modifications are required for your code, while the standard Matlab-code is kept clean.
A slightly less convenient method would be a menu in the command windows main frame, where a figure selector appears. But this seems to required more work to allow a convenient method to select a figure.
David
David le 3 Oct 2013
Oh awesome idea thanks.
So I've almost got it working, but for some reason its not recognizing the file as a matlab binary when I attempt to open the figure in the final paste step.
In other words... i'm able to save to the hard drive with hgsave, read back in with fread, add a magic flag, clipboard and back, remove the flag and fwrite to a file, but then openfig fails, saying:
Unable to read MAT-file C:\Users\dare4983\AppData\Local\Temp\FigForClipboard.fig: not a binary MAT-file. Try LOAD -ASCII to read as text.
Here is what the file looks like:
MATLAB 5.0 MAT-file, Platform: PCWIN64, Created on: Thu Oct 03 12:25:42 2013
I've tried doing fread,fwrite with uint8 instead of char, no help there. I think that the concatenation with the magic flag is recasting the stream into a char array no matter what I tell fread to do, but I'm not sure how to manually recast to uint8 before the fwrite step. You'd think fwrite would do this automatically though if I tell it to make a uint8 file?
I've also tried messing around with fwrite parameters. I tried telling it bit1 to write in binary, or switching to Bigendian but still no luck.
Jan
Jan le 4 Oct 2013
@David: I will take a look on this at the weekend.
Jan
Jan le 5 Oct 2013
Code in my answer replaced by a working version.

Connectez-vous pour commenter.

Plus de réponses (1)

Björn
Björn le 18 Sep 2013
For the last part you could consider saving the figure as .fig and then copy the file to the other computer. Here you can open de figure with full compatibility and all data preserved.
To display certain parameters of the figure you can use the get function. For example for getting the title you use:
get(get(gca,'title'),'string')
The inner 'get' retrieves the title of the current axes ('gca'). The outer 'get' converts it to a string.
In case you have more figures open then you have to have the axes-handle of figure-handle for the right figure but this is a bit more complicated. If you need that too, just let me know.

3 commentaires

David
David le 18 Sep 2013
Hi Bjorn,
This is certainly a workaround but much much slower than I am hoping for. My hope is to be able to move a figure or a trace from one matlab to another with the ease of copy-paste.
For example in plot edit mode it is super useful to be able to copy paste axes, traces, titles, or anything between different figures. I am looking for this same speed and versatility but between two instances of matlab.
Perhaps there is a way that I can write a script that would add a menu option or a keyboard shortcut to the plot edit mode for pushing figure data to the system clipboard?
David
Hi David,
If the main problem now is to get it automatically to the clipboard, you can make script that does the following:
function str = clipboard_plot_data(parameters,axes_handle)
[par_nr,~]=size(parameters);
str='';
for i=1:par_nr
if nargin < 2
str_test=get(get(gca,parameters{i}),'string');
str_t=['\' parss '=' str_test ' \' parss '\'];
else
str_test=get(get(axes_handle,parameters{i}),'string');
str_t=['\' parss '=' str_test ' \' parss '\'];
end
str=[str str_t];
end
clipboard('copy',str)
This will copy a string with all the data to the clipboard. You can use
clipboard('paste')
to paste is to the clipboard again. The input parameters of the function are of the form:
parameters={'title';'xlabel';'ylabel'}
If you don't input the axes-handle it will use the current axes.
The actual parameters are located between '\title=' and '\title\' Hence, finding those parts in the string will get you the title.
David
David le 24 Sep 2013
Hi Bjorn, this is pretty cool, but I'm not sure how to get this into a really easy use format. I don't want to have to run a separate script each time I try to copy and paste a figure to a different matlab.

Connectez-vous pour commenter.

Catégories

En savoir plus sur Creating, Deleting, and Querying Graphics Objects dans Centre d'aide et File Exchange

Question posée :

le 17 Sep 2013

Commenté :

Jan
le 5 Oct 2013

Community Treasure Hunt

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

Start Hunting!

Translated by