How can I convert matlab code to image? - matlab

For exmaple,I have the following code.
% Generate random data from a uniform distribution
% and calculate the mean. Plot the data and the mean.
n = 50; % 50 data points
r = rand(n,1);
plot(r)
% Draw a line from (0,m) to (n,m)
m = mean(r);
hold on
plot([0,n],[m,m])
hold off
title('Mean of Random Uniform Data')
for v = 1.0:-0.2:0.0
disp(v)
end
I want to convert MATLAB code to an image.
For example, if you copy the MATLAB code into a software then it return the image like this:
How to do it?
If I use this code and publish it to PDF file,the code is not completely display.
sumLumi(x,y)=LLmap3(floor(x/4)+1,floor(y/4)+1)+LLmap3(floor(x/4)+2,floor(y/4)+1)+LLmap3(floor(x/4)+1,floor(y/4)+2)+LLmap3(floor(x/4)+2,floor(y/4)+2);

From the MATLAB editor you can Publish your document as a PDF (by changing the Output file format to pdf under publishing options). It will also evaluate the code unless you change the Publishing Options>Code Settings>Evaluate code to false.
The PDF can then can converted to an image (a quick google search gives an online PDF to JPG converter).
You can break a line and continue on the next with ..., for example
sumLumi(x,y)=LLmap3(floor(x/4)+1,floor(y/4)+1)+LLmap3(floor(x/4)+2,floor(y/4)+1)+LLmap3(floor(x/4)+1,floor(y/4)+2)+LLmap3(floor(x/4)+2,floor(y/4)+2);
can be written as
sumLumi(x,y) = LLmap3(floor(x/4)+1, floor(y/4)+1) ...
+ LLmap3(floor(x/4)+2, floor(y/4)+1) ...
+ LLmap3(floor(x/4)+1, floor(y/4)+2) ...
+ LLmap3(floor(x/4)+2, floor(y/4)+2);

If you want to use Matlab only you can use this workflow:
Make your code to be single .m file. Any text file will work.
Read this file in cell column vector Code;
Process the lines adding using TeX or LaTeX formatting commands;
Create white figure with text(x,y,Code);
Export the figure.
This might be good way to produce many figures with same style.

Related

Efficiency loading a file into Matlab

I am trying to load a file in Matlab. But I am a bit confused about the best way to do it.
The file has 3 columns and looks like the screenshot below:
This file I can load very quickly by doing load('c').
However, I had to add 2 NaNs on the bottom row.
The original file actually looks like the file below:
Now if I do load('c') on the file below I get the error:
Error using load
Unable to read file 'c'. Input must be a MAT-file or an ASCII file containing numeric
data with same number of columns in each row.
Of course I can use ImportData to import this file, but it is just soooo slow to import it.
Any suggestions?
You should be able to use c = readtable('c'). This should automatically change the empty entries to "NaN" by default, but if not, there is a way to set that in the options.
If I have a file that is tricky to import (prior to readtable()...that made things a lot easier in the last few years), I will often use the Import Data tool (if its a really big file you can make a mock-up of the complicated file so it loads faster) then change all the import settings as I would want it, then where the green check says "Import Selection" use the black drop down arrow to select "Generate Function." This will give you the coded way of setting everything up to get the file in just the way you want it.
load() is better suited for reading in previously saved '.mat' files that were created in Matlab.
Here's a low-level approach, which might be faster than other methods:
filename = 'c'; % name of the file
N = 3; % number of columns
fid = fopen(filename, 'r'); % open file for reading
x = fscanf(fid, '%f'); % read all values as a column vector
fclose(fid); % close file
x = [x; NaN(N-mod(numel(x)-1,N)-1, 1)]; % include NaN's to make length a multiple of N
x = reshape(x, N, []).'; % reshape to N columns in row-major order

How to generate valid HyperStack ImageJ data files from Matlab?

ImageJ HyperStacks have a data type (8-32 bit), a width, a height, a number of channels, a number of slices and a number of frames. They represent 5D (XYCZT) data sets. ImageJ stores them as multipage tiff files where number of channels times number of slices times number of frames 2D (XY) images are stored. The first image seems to have two custom tags with IDs 50838 and 50839.
I want to create tif files containing 5D data from Matlab that can be read by ImageJ as a valid 5D HyperStack.
I can store a number of 2D images in a multipage tiff file in Matlab using imwrite(matrix, file, 'WriteMode','append') but ImageJ will read that as 3D (XYZ) image stack only. The information about the channels, slices and frames is not contained.
I guess I could look at the ImageJ sources to find out where they store this missing information, then use Matlab's wrapper of LibTIFF to recreate the meta information of ImageJ. If you, however, already know what to do or if there is an alternative, I would like to hear it.
I also thought that Bio-Fomats was the only way. But then I realized that Fiji's ImageJ-MATLAB allows you to pass MATLAB data to ImageJ. Then, you can save the image by ImageJ, so ImageJ can open it for sure.
The problem was that people (or just one guy?) created ImageJ-MATLAB did a great job in creating a route from MATLAB to ImageJ, but they didn't seem to bother optmizing the behaviour. ImageJ-MATLAB's IJM.show('name') had a lot of hidden or undocumented limitations (I massively changed the documentation, so it should be clearer now). Eventually, I enede up wriring a wrapper function
ijmshow
https://github.com/kouichi-c-nakamura/ijmshow
Example MATLAB code
You can do it with 4 lines.
addpath '/Applications/Fiji.app/scripts' % depends your Fiji installation
ImageJ
imp = ijmshow(I,'YXCZT') % I is 5D array of uint8 or uint16
% the second argument determines which dimension represents what
% imp is a 5D hyperstack
ij.IJ.saveAsTiff(imp, 'image1.tif');
You may want to set Display Range of each channel before saving.
Added on 5/7/2018
copytoImagePlus provides better solution than ijmshow above (you can use the same syntax), because copytoImagePlus does not rely on the IJM variable in the base workspace anymore.
https://github.com/kouichi-c-nakamura/copytoImagePlus
addpath '/Applications/Fiji.app/scripts' % depends your Fiji installation
ImageJ
imp = copytoImagePlus(I,'YXCZT') % I is 5D array of uint8 or uint16
% the second argument determines which dimension represents what
% imp is a 5D hyperstack
ij.IJ.saveAsTiff(imp, 'image1.tif');
Also see copytoImgPlus which create ImageJ2 ImgPlus object instead.
https://github.com/fiji/fiji/blob/master/scripts/copytoImgPlus.m
ImageJ uses the ImageDescription tag of the TIFF's first IFD to store its meta-information. Here is an example from the Mitosis sample dataset (File > Open Samples > Mitosis):
ImageJ=1.51d
images=510
channels=2
slices=5
frames=51
hyperstack=true
mode=composite
unit=\u00B5m
finterval=0.14285714285714285
loop=false
min=1582.0
max=6440.0
MATLAB's Tiff class might give you fine-grained enough control to write a custom ImageDescription to the first IFD; I am not sure.
Probably easier would be to use the Bio-Formats library's bfsave.m function to write OME-TIFF, which can be 5-dimensional; ImageJ can read this format via the Bio-Formats plugin. I recommend using the Fiji distribution of ImageJ, which comes with Bio-Formats pre-installed.
There was also this same question posted on MATLAB Central.
Using Matlab's Tiff class.
I can assemble an ImageDescription tag that I think looks fine and ImageJ reads it (File>Open) as a 5D Hyperstack but the data is partly corrupted. There seem to be offset problems (I can read the data just fine in again with Matlab).
However, if reading the tiff file with File>Import>Bio-Formats it becomes 5D (XYCZT) stack in ImageJ if view stack with Hyperstack is marked in the Bio-Formats import dialog. Thanks to ctrueden for his helpful comment.
d = ones(100, 200, 10, 2, 3, 'single') * 3.765;
hyperstack_write('test.tif', d);
function hyperstack_write(file, hyperstack)
% Writes an (up to) 5D stack into a (XYCZT) HyperStack Tiff file
% readable by ImageJ
%
% hyperstack must have class single
% simple checks
assert(nargin == 2, 'Not enough arguments');
assert(isa(hyperstack, 'single'), 'hyperstack must be single');
% get all five dimensions
d = zeros(5, 1);
for i = 1 : 5
d(i) = size(hyperstack, i);
end
% assemble image description
s = sprintf('ImageJ=1.51\nnimages=%d\nchannels=%d\nslices=%d\nframes=%d\nhyperstack=true\nmode=color\nloop=false\nmin=%.1f\nmax=%.1f\n', prod(d(3:5)), d(3), d(4), d(5), floor(min(hyperstack(:))*10)/10, ceil(max(hyperstack(:))*10)/10);
% open tif file for writing and set file tags
t = Tiff(file, 'w');
ts.ImageLength = d(1);
ts.ImageWidth = d(2);
ts.Photometric = Tiff.Photometric.MinIsBlack;
ts.Compression = Tiff.Compression.None;
ts.BitsPerSample = 32;
ts.SamplesPerPixel = 1;
ts.SampleFormat = Tiff.SampleFormat.IEEEFP;
ts.RowsPerStrip = 5;
ts.PlanarConfiguration = Tiff.PlanarConfiguration.Chunky;
ts.Software = 'MATLAB';
ts.ImageDescription = s;
% loop over dimensions 3, 4, and 5
for k = 1 : d(5)
for j = 1 : d(4)
for i = 1 : d(3)
frame = hyperstack(:, :, i, j, k);
t.setTag(ts)
t.write(frame);
t.writeDirectory();
end
end
end
% close tif file
t.close();
end
It seems Bio-Formats is the only fully paved and available way to export >2D data from Matlab to ImageJ, although this solution here could be a lightweight alternative in cases where not much metadata is available and needs to be transferred.

Create Matlab figures in LaTeX using matlabfrag or alternatives

I want to include Matlab figures into latex preferably with vectorised formats but with LaTeX MATLAB fonts for all text. I have been using the MATLAB function matlab2tikz which worked perfect for simple figures, but now my figures have too many data points which cause an error. So matlab2tikz is not suitable.
I've been looking at matlabfrag which I think will accomplish what I want, but when I run the script in LaTeX as detailed by the user guide it has an error File not found.
This is my code:
\documentclass{article}
\usepackage{pstool}
\begin{document}
\psfragfig{FileName}
\end{document}
Where FileName is the name of the .eps and .tex that matlabfrag creates. Has anyone come across this problem? Or recommend any other functions/methods to use?
I'm using Texmaker on Windows 7.
My advice would be to rethink your workflow.
Instead of reusing your Matlab code to plot figures and be dissappointed by ever changing outputs with matlab2tikz, start reusing your latex code to plot figures and don't bother about plotting in Matlab anymore (at least not for beautiful plots).
matlab2tikz is just generating latex code based on the latex-package pgfplots. To understand the working of this package is pretty easy, as it is intended to be similar to Matlab.
So why bother and always let matlab2tikz do the work for you? Because again and again you won't be entirely happy with the results. Just try to write the pgfplots-code from scratch and just load the data from Matlab.
Here is a convenient function I wrote to create latex-ready text files:
function output = saveData( filename, header, varargin )
in = varargin;
numCols = numel(in);
if all(cellfun(#isvector, in))
maxLength = max(cellfun(#numel, in));
output = cell2mat(cellfun(#(x) [x(:); NaN(maxLength - numel(x) + 1,1)],in,'uni',0));
fid = fopen(filename, 'w');
fprintf(fid, [repmat('%s\t',1,numCols),'\r\n'], header{:});
fclose(fid);
dlmwrite(filename,output,'-append','delimiter','\t','precision','%.6f','newline', 'pc');
else
disp('saveData: only vector inputs allowed')
end
end
Which could for example look like the following, in case of a bode diagram:
w G0_mag G0_phase GF_mag GF_phase
10.000000 40.865743 -169.818991 0.077716 -0.092491
10.309866 40.345290 -169.511901 0.082456 -0.101188
10.629333 39.825421 -169.196073 0.087474 -0.110690
10.958700 39.306171 -168.871307 0.092787 -0.121071
11.298273 38.787575 -168.537404 0.098411 -0.132411
In your tikzpicture you can then just load that file by
\pgfplotstableread[skip first n=1]{mydata.txt}\mydata
and store the table into the variable \mydata.
Now check pfgplots how to plot your data. You will find the basic plot command \addplot
\addplot table [x expr= \thisrowno{0}, y expr= \thisrowno{3} ] from \mydata;
where you directly access the columns of your text file by \thisrowno{0} (confusing, I know).
Regarding your problem with to many data points: pgfplots offers the key each nth point={ ... } to speed things up. But I'd rather filter/decimate the data already in Matlab.
The other way around is also possible, if you have to few data points the key smooth smoothes things up.

Interact with very large Tiff (or rset) images in MATLAB

I have some very large Tiff images that I am trying to use in a MATLAB GUI application. If I try to load the images using imshow, I get an out-of-memory error. (Yes, I know MATLAB is not the best choice for GUIs or loading large images, but there is good reason for using MATLAB in this case).
I can obviously create a reduced resolution data set (rset file) and use imtool to view the image, but this is not helpful as I want a user to be able to interact with the image by clicking on it to extract (x,y) coords into the application. Imshow does not seem to be directly compatible with rset files. Is there a way for me to load an rset'd image in a panable/zoomable figure, or any other way I can achieve the goal?
I looked at the code for imtool but it seems to be using undocumented classes to read rset files and I can't replicate its behaviour.
You can use low-level file I/O functions of MATLAB to read the entirety or parts of the TIFF image in order to avoid the OOM problem.
fileName = 'LargeTiff.tif';
info = imfinfo(fileName)
% Determine number of frames
nFramesStr= regexp(info.ImageDescription, 'images=(\d*)', 'tokens');
nFrames = str2double(nFramesStr{1}{1});
% Use low-level File I/O functions to read the file
fp = fopen(fileName , 'rb');
% The "StripOffsets" field provides the offset to the first strip.
fseek(fp, info.StripOffsets, 'bof');
% Assume that the image format is 16-bit per pixel and is big-endian
% Also assume that the images are stored one after the other
% For example, read the first 100 frames
frameNum = 100;
imData = cell(1, frameNum);
for cnt = 1 : frameNum
imData{cnt} = fread(fp, [info.Width info.Height], 'uint16', 0, 'ieee-be');
end
fclose(fp);
It looks like my problem is that I simply don't have enough memory to load the whole tiff, and that there is no public specification for the rset files format. So I am going to instead solve the problem by creating my own version of a reduced resolution data set. I should be able to load block sections of the image, resave them and then dynamically load and unload only the needed high-res blocks at zoom, and load a reduced resolution overview when zoomed out.
You can write a callback function to get the pixel co-ordinates (X,Y) from imtool then convert to a tile number and tile index using the code below. You can then utilise the readencodedtile function in matlab
function [tileidx,Tile_num] = getTileInfo(tiffile,X,Y)
A = Tiff(tiffile);
tile_width = A.getTag('TileWidth');
tile_length = A.getTag('TileLength');
SizeA = size(A);
tt = sub2ind(SizeA,X,Y);
% Example only
% X = repmat((1:10)',1,10);
% Y = repmat((1:10),10,1);
% A = reshape(1:100,10,10);
% SizeA = size(A);
% tile_width = 3;
% tile_length = 2;
tileidx = rem(tt-(Y-1)*SizeA(1)-1,tile_length)+1 ...
+ tile_length*rem(Y+tile_width-1,tile_width);
Tile_num = ceil(Y/tile_width)+ ...
(ceil(X/tile_length)-1)*ceil(SizeA(2)/tile_width);

matlab printing splitted plot to file

I'm creating a code to do data analysis that will run on a server. The code is supposed to spit a pdf file with 3 plots on it.
I have created a code that generates the plot
fig = figure;
for i = 1:3
%do some calculation to find, X, Y and fit
subplot(3,1,i)
scatter(X,Y)
hold on
plot(X,fit)
end
print (fig, '-dpdf','fig.pdf')
X, Y, and fit are calculated/imported parameters. The output of this code is a pdf document with only the last plot on it (missing the first two).
How can I print all three of them to file?
I tried your code on my CPU (X,Y and fit were generated randomly) and it works fine, so the bug may come from the interaction of this snip of code with you "%do some calculations block"
I would suggest to add a "hold off" command before the end of the for loop ...
gus