Is there a way of selectively including code when publishing in Matlab? - matlab

I'm writing MATLAB code in order to publish it later. By publishing, I mean the built-in MATLAB publish tool that allows the programmer to make a full report generated from their MATLAB code. There's an option to include the code with this report, section by section, preceding the results of this code. Is there a way to tell MATLAB to include some of this code in the report but not all of it? I know there are quite a few markup code tags, but I wasn't able to find anything on this topic.
Edit: Just to clarify, I want all results to be published, but only some of the code. So simply removing this code is not an option.
Cheers! = )

Hide your code that you don't want people to see in a script. For example, in the "sine_wave" example from the publish documentation page, I added a single line:
junk
Here's the content of junk:
figure()
plot(0:0.01:6,sin(0:0.01:6))
Now run your main script, and the published result has "junk" in the listing, but the contents of junk are not included, and you get the nice version of a sine wave, instead of the crappy one included in their example.

The only way I know of to do this is to remove the code that you don't want to appear in the output. If you just want to display the code and not the output, then you can just set the evalCode property to false in your call to publish.
If you do want the code to be evaluated, and the output to be published as well, then it's just slightly more complicated. You can manually execute the parts of the script that you don't want to publish, then publish the code that you care about (by putting it in it's own .m file). It shouldn't matter if the published code depends on any variables that are initialized in the omitted code, since those variables were added to your workspace when you manually executed the omitted code fragments.
Edit:
Since you've clarified your question to state that you're interested in publishing some of the code, but all of the output, I would think that your best bet is to just modify the "temporary" script (which contains the partial set of code that you wish to publish) to include any fprintf, disp, etc. function calls that you want to have appear in the output.
It's a bit hack-ish, but like I said, I'm not aware of any way to get that kind of fine granularity with "annotations" or using the publish command.
Hope that helps!

Here's a sample script that you can save and publish which will illustrate one workaround. You first have to set the Include code option to false, which stops all evaluated code from appearing, but you can still display code using a syntax highlighted code sample:
%% Controlling what code gets published
% Here's how you can do it...
%% Showing results without code
% If you set the
% <https://www.mathworks.com/help/matlab/matlab_prog/specifying-output-preferences-for-publishing.html#bthbe__-3
% *Include code* option> to |false|, you will see the plot but not the code
% that made it:
surf(peaks); % I'm John Cena!
%% But what if you want some of the code to show?
% The *Include code* setting affects the whole document, so all evaluated
% code will be hidden. If you want some code to show, you can use
% <https://www.mathworks.com/help/matlab/matlab_prog/marking-up-matlab-comments-for-publishing.html#bs_uwzr
% syntax highlighted sample code>. This does mean you have to have duplicate
% sections of code (one is evaluated, one is displayed), but it's the best
% option thus far:
%%
%
% surf(peaks);
%
surf(peaks); % You can't see me, but you see the above!
And here's the published output:

I change the Matlab expression in the publishing options to
myFunction('PUBLISHING');
And the first lines of the function code to check for that input, so I can modify my code to only do certain things when publishing, usually displaying figures etc., but not during normal operation. Or vice versa :)
function [outputs] = myFunction(input1, input2)
isPublishing = (nargin == 1) && strcmp(input1, 'PUBLISHING');
if (nargin == 0) || isPublishing
% Set up default values
input1 = 'Hello';
input2 = 'World';
end
...
end

Related

How to control the figure which appears in bayesopt function?

bayesopt draws figures like this:
How to access such figures in order to modify title or something? If I use gcf it is not guaranteed I get the correct figure because I could change focus to another figure window during execution.
Apparently bayesopt does not allow you to return a figure handle. So I suggest that on the line directly after your call to bayesopt you call h=gcf;, thus forcing your program to return the figure handle to h, which can then be modified at any desired time, even when moving to other figures.
results = bayesopt(fun,vars,Name,Value); % execute bayesian optimisation
h = gcf; % directly after optimisation grab a figure handle
Now you can modify properties in h, e.g. for the title you'd simply do
h.CurrentAxes.Title.String = 'Your plot title'
The reason this works is that MATLAB does not display figures until the full code has finished running. At least that's the case for my script, where I generate a figure, perform a few minutes of optimisation, then generate another figure. Both figures get displayed at the same time, i.e. when MATLAB has finished running the full program. There's thus no way you can click other figures when the code is running, since they are simply not there. If you happen to have older figures open (from other scripts), focus gets shifted to the latest created figure anyway, the moment it's created in the code (so not when it's displayed), thus you'd need to click a figure in the few milliseconds between the bayesopt call finished and the gcf call, which I'd say is so improbable that it's not worth considering, especially since it requires manual intervention.
As was pointed out in comments by Cris Luengo and Dev-iL, the figures are tagged and can thus be found using findobj:
h1 = findobj(0,'tag','bayesopt.MinObjective')

Execute Example Code in Matlab when Publishing a Function

Background
Matlab has a publish function which outputs a, say, .html file based on the syntax of the comments. Sections which contain example code are indicated by a '%' followed by three spaces. An example function can be seen below, and the .html file generated by the publish function can be seen here.
function randomImage = GenerateRandomImage(n)
%% TestFunction
% generates a random image
%
% randomImage = GenerateRandomImage(n) returns an nxn array of random pixels
%
%% Example
% randomImage = GenerateRandomImage(10);
% figure; imagesc(abs(randomImage));
randomImage = rand(n);
end
Matlab will not automatically evaluate the example code, unless I create a separate script with the example code explicitly uncommitted. An example script is seen below. This time, it automatically includes the outputs of that script, such as the image produced by the example script shown here here.
%% TestFunction
% generates a random image
%
% randomImage = GenerateRandomImage(n) returns an nxn array of random pixels
%
%% Example
randomImage = GenerateRandomImage(10);
figure; imagesc(abs(randomImage));
The Question
Is it possible for the publish function to automatically evaluate the code snippits in the comments of a function and include those outputs in the html file?
The matlab publisher is explicitly meant to be performed on scripts, not function files, since its purpose is to produce a report, where individual sections (marked with %%) become headings, and lines beginning with % immediately under the %% become the description text for that section. Anything that follows after that, both code and comment lines, will be presented by the publisher in a nice little box as the code that was run for that section, and then the results of that code will be shown below that box, but contained within their section.
Putting code in the description text for that section, expecting it to be run is counter-intuitive. In fact, the only reason you might want to put a code snippet in the description is if you wanted to mention some code without running it.
For this reason the publisher provides special syntax (indent by 2 spaces for monotyped text, 3 spaces to add syntax-highlighting to your code).
Publisher is a nice tool, but unfortunately it's fairly limited. The main limitation for me is that you cannot choose which code sections to show results for and which ones not to; it's all or nothing. Therefore I usually resort to a "latex + saved matlab figures + makefile" approach instead for flexible reports. But publisher is nice if you want something quick and dirty; e.g. it's good for keeping a logbook / diary of your work.
Anyway, to answer your question, no, you can't put code in the description and expect it to run. Nor are you expected to 'publish' functions; the fact that a function file responds at all to publishing in the first place is probably more of a side-effect of how publisher gets called more than anything.

Matlab Publish Image PDF

I want to include a picture of my Simulink diagram when I publish my script. I currently print it to an image and manually add it in later.
I read on the Matlab website that I could do this by including a comment <<FILENAME.jpg>> and the publishing tool would pick it up and add it to my report. Unfortunately all this does is add a link to the image, which is not helpful when printing it out.
This is what I have:
print(['-s',simName], '-djpeg', ['html/',simName,'.jpg'])
% <<simName.jpg>>
I've also tried these tips before, but they didn't work for me either.
What you have tried should work. In fact it should work with any JPG file. have you tried what the example from the documentation?
To produce an HTML file containing surfpeaks.jpg from a MATLAB file:
Create a subfolder called html in your current folder.
Create surfpeaks.jpg by running this code in the Command Window.
saveas(surf(peaks),'html/surfpeaks.jpg');
Publish this MATLAB code to HTML.
%% Image Example
% This is a graphic:
%
% <<surfpeaks.jpg>>
%
The alternative is to open the Simulink system with open_system. This will create a snapshot of the model in the published HTML provided the model is closed when the open_system command is issued.
%% Include snapshot of f14 model
%
open_system('f14')
%
If none of these work, then there's something fundamentally wrong with your MATLAB installation, of the way you are using the publish command.
open_system('filename.slx')
make sure the simulink program is in the same folder as the script.

MATLAB: Permanently set "Text Update Function" for Data Cursor in figures

Problem: I use MATLAB for science, and I often need more than 4 significant digits. Every time I use Data Cursor in a figure's GUI, I need to manually right-click on the point, Select Text Update Function... or Edit Text Update Function..., and navigate to the folder where I saved the function whose callback prints more than 4 (e.g. 8) significant figures. This is annoying and there should be a way to automatically change this.
Ideal answer: I want this done permanently for all figures, e.g. in a function that changes default settings in my startup.m file.
Good enough answer: I want a wrapped function to which I give the figure handle and it fixes this for me.
I humbly await SO's infinite wisdom.
The permanent solution
would be, to edit the default_getDatatipText.m function.
You can find it in:
C:\...\MATLAB\R20xxx\toolbox\matlab\graphics\#graphics\#datacursor
There you will find the line:
DEFAULT_DIGITS = 4; % Display 4 digits of x,y position
Edit it as desired, you can't do much harm, but make a backup before if you want.
Alternative solution:
There is also the possibility of custom data tips: Tutorial at Matlab Central
It could finally look like this:
(additional text outside data-tips was post-processed)
And as you're talking about precision. The data-tip always snaps to the closest data-point. It doesn't show interpolated data at the clicked position.
The permanent answer given by thewaywewalk doesn't work anymore in R2015a, and probably later ones. So here I share my solution for both the temporary and permanent solution
Temporary solution (for a single figure):
The following function contains the update function as a nested function. Call datacursorextra to apply it to the current figure, or datacursorextra(fig) to apply it to some figure fig.
function datacursorextra(fig)
% Use current figure as default
if nargin<1
fig = gcf;
end
% Get the figure's datacursormode, and set the update function
h = datacursormode(fig);
set(h,'UpdateFcn',#myupdatefcn)
% The actual update function
function txt = myupdatefcn(~,event)
% Short-hand to write X, Y and if available Z, with 10 digit precision:
lbl = 'XYZ';
txt = arrayfun(#(s,g)sprintf('%s: %.10g',s,g), lbl(1:length(event.Position)), event.Position,'uniformoutput',false);
% If a DataIndex is available, show that also:
info = getCursorInfo(h);
if isfield(info,'DataIndex')
txt{end+1} = sprintf('Index: %d', info.DataIndex);
end
end
end
Permanent solution (apply to all figures by default):
I have not found a way to set a default UpdateFcn for the data cursor, but it is possible to add some code which will be called every time a new figure is created. Add the following line to your startup.m:
set(0,'defaultFigureCreateFcn',#(s,e)datacursorextra(s))
and make sure the datacursorextra function given above is available in your Matlab path.
#caspar's solution works very well.
You can also update the txt{} part of the solution with
if isfield(info,'DataIndex')
DataIndex = [info.DataIndex];
txt{end+1} = sprintf('Index: %d\n', DataIndex(1));
end
This will enable you to update the Index field when you have multiple pointers in the same figure.

MATLAB m-file help formatting

I could not find what formatting available to write help for your own MATLAB function. Very little information is available in official documentation.
Do you know about any other formatting that can be visible with Help Browser (not with help function)? As it is for built-in functions. How to format headings (like Syntax, Description, Examples)? Are bullets, tables possible? Or may be it should be a separate file?
I've tried text markup as used for PUBLISH and HTML, didn't work.
I found only one interesting thing. If your function contains mixed case, like testHelpFunction, its name will be highlighted:
No highlighting if it's just testhelpfunction.
Any other thoughts?
UPDATE
Here is extensive documentation I found on creating your own help files:
Providing Your Own Help and Demos
(Dead link replaced with web archive link)
(Dead link removed)
Updated again:
Add Help for Your Program
Display Custom Documentation
Try this other section in the official documentation. It's more thorough. MATLAB > User's Guide > Desktop Tools and Development Environment > Customizing Help and Demos > Providing Your Own Help and Demos. This describes both simple helptext and generating separate HTML help files.
Here's the helptext formatting I've picked up on and found useful.
function foo(x,y,z)
%FOO One-line description goes here
%
% foo(x,y,z)
%
% Multi-line paragraphs of descriptive text go here. It's fine for them to
% span lines. It's treated as preformatted text; help() and doc() will not
% re-wrap lines. In the editor, you can highlight paragraphs, right-click,
% and choose "Wrap selected comments" to re-flow the text.
%
% More detailed help is in the extended help.
% It's broken out like this so you can keep the main "help foo" text on
% a single screen, and then break out obscure parts to separate sections.
%
% Examples:
% foo(1,2,3)
%
% See also:
% BAR
% SOMECLASS/SOMEMETHOD
disp(x+y+z);
function extended_help
%EXTENDED_HELP Some additional technical details and examples
%
% Here is where you would put additional examples, technical discussions,
% documentation on obscure features and options, and so on.
error('This is a placeholder function just for helptext');
The first line after the function signature is called the "H1 line". It needs to be just one line so it is properly picked up by contentsrpt(), which can autogenerate a Contents.m file from the helptext in your functions
The function name in the H1 line is all caps, regardless of actual capitalization of the function name in the signature
Case matters for the "See also". I'm not sure which all cases work; this one does for sure.
Function names after "See also:" are all caps. Method names are qualified; I think names of methods in the same class as the current method can be unqualified.
Everything between the H1 line and "Examples:" is just a conventional formatting that I find readable; help() doesn't treat it specially.
You can use a limited form of hyperlinks in help. In particular, you can use hyperlinks to invoke arbitrary Matlab commands, and point to other sections of helptext by having it invoke help(). You can use this to point to any function; "function>subfunction" is just the syntax for addressing subfunctions in help() calls. Unfortunately, since you need to put either "help" or "doc" in those hyperlinks, it only works in one or the other presentation form. It would be nicer if there were a direct helptext hyperlink form.
I think the most important aspect in help formatting is that there is a help at all, and that your formatting is consistent, so that you (and people working with you) don't waste time finding out how to look for the information. Note that for OOP, it is useful to have a superclass with a 'help'-method that calls doc(class(obj)), since you cannot easily access the help from an instantiation of your class
To help me be consistent (and to make sure I don't forget stuff), I have created an automatic function template on the file exchange.
Here's the minimal header
function testhelp
%TESTHELP is an example (this is the H1 line)
%
% SYNOPSIS: a=testhelp(b,c)
%
% INPUT b: some input parameter
% c: (opt) some optional input parameter. Default: []
%
% OUTPUT a: some output parameter
%
% REMARKS This is just an example, it won't run
%
% SEE ALSO testHelpFunction
%
% created with MATLAB ver.: 7.11.0.584 (R2010b) on Mac OS X Version: 10.6.4 Build: 10F569
%
% created by: Jonas
% DATE: 01-Oct-2010
%
I figure there is some (see example), but I've never found the appropriate documentation. I often have such blocks:
% ...
%
% See also:
% this_other_function()
%
% <author>
And the See also part is formatted as a title, but if you replace See also by something else, it doesn't work. If anyone finds the list of such supported titles, please link to it here!
EDIT:
I've recently come to learn about matlab's built-in publishing system. It seems MATLAB comments support some form of markup not so far from Markdown's syntax (as used on SO itself), with support for LaTeX equations and all.
There's a post by "Loren on the art of MATLAB" with a short introduction on publishing and markup. For a full reference, see Making Up MATLAB Comments for Publishing on the Mathworks website.
When your code is ready, you can export the result to HTML/PDF/XML, etc. using the publish() function. I use the following snippet to export my files:
% Other formats are supported, refer to documentation.
options.format = 'html';
% I don't evaluate the code, especially for functions that require arguments.
% However, if providing a demo, turning this on is a fantastic way to embed
% figures in the resulting document.
options.evalCode = false;
% You can run this in a loop over files in the currrent directory if desired.
publish('script.m', options);