I would like someone to explain to me those lines of code, please. It might be important to mention that this code is part of a display function.
if isa(obj,'PhArea')
disp(t)
elseif isequal(get(0,'FormatSpacing'),'compact')
disp([inputname(1) '='];
disp(t);
else%that is format loose
disp(' ')
disp([inputname(1) ' =']);
disp(' ');
disp(t)
end
This code just determines how to display the value of a variable t depending on the type of t as well as the current format settings.
% If this is a PhArea instance
if isa(t, 'PhArea)
% Then just display it
disp(t)
% If the user has enabled compact formatting (format compact)
elseif isequal(get(0, 'formatspacing'), 'compact')
% Display the variable's name and an equal sign (no spaces)
disp([inputname(1), '='])
% Display the variable itself
disp(t)
% Otherwise
else
% Display an empty line
disp(' ')
% Display the variable's name and an equal sign (with space)
disp([inputname(1), ' ='])
% Display an empty line
disp(' ')
% Display the variable
disp(t)
end
Update
The following line is the trickiest here.
isequal(get(0, 'formatspacing'), 'compact')
What this does is retrieves the current format spacing. The 0 is the graphics root object which is used to store information that applies to a given MATLAB session. When the user specifies that they want to use 'compact' format spacing, this configuration is stored within the root object.
format loose
get(0, 'formatspacing')
% loose
format compact
get(0, 'formatspacing')
% compact
So by retrieving the current setting as a string, you can then compare it (using isequal) to 'compact' to see if the user wants to use compact format spacing or not.
Related
I have below these three vectors:
CoverageArea_mean = [84.4735,0,21.1779,4.5211,6.4247,2.3795,2.1416,0]; %FEC = 3.8x10^-3
CoverageArea_min = [98.5128,92.5640,21.1779,21.1779,6.9007,6.9007,2.1416,2.1416]; %FEC = 3.8x10^-3
CoverageArea_max = [70.1963,0,19.0363,0.4759,5.9488,0.2380,2.1416,0]; %FEC = 3.8x10^-3
I would like to draw them as in the figure below:
x = [15 15 30 30 45 45 60 60];
I am not sure If they will be fit for the box plot or not. I want to take a value from the three vectors every time and represent them as a above.
Any idea or assistance, please?
1.- I call marker (as in oscilloscopes) what in MATLAB is called pointer.
2.- I have modified Davidson's function plot_candlesticks available here
https://uk.mathworks.com/matlabcentral/fileexchange/9893-candlesticks?s_tid=srchtitle_financial%20charts_23
Mathworks File exchange name: candlesticks version 1.0.0.0 (1.44 KB) by Bill Davidson
Bill grants permission for modifications.
3.- With the following functions and test script you can generate graphs like this
The addition of text labels is a really easy task that I have started, as you can see in the test script, but ran out of time for this question so I let you finish it off, let me know if you encounter any problem.
I recommend you use command text outside the supplied functions, after plotting the graph
4.- I give you 2 functions: plot_tees and plot_bars . The function you asked for is plot_tees
function [hpt]=plot_tees(ax1,x,highs,lows,opens,closes,sh,col_stick)
% plot_tees plots T and inverted T on supplied data points
% input checks: PENDING
% make sure x has no gaps and same interval
% make sure all input lengths are the same : x highs lows opens closes
% check amount inputs and expected formats ok
middle=sh.middle
hwbody=sh.hwbody
hwshad=sh.hwshad
xbody=sh.xbody
xshad=sh.xshad
npoints=length(highs);
hpt=[0 0 0];
for k1=1:npoints
hp1(k1,1)=plot(ax1,[.5+x(k1)-.2 .5+x(k1)+.2],[highs(k1) highs(k1)],'Color',col_stick,'LineWidth',1.1); % top --
hp1(k1,2)=plot(ax1,[.5+x(k1)-.2 .5+x(k1)+.2],[lows(k1) lows(k1)],'Color',col_stick,'LineWidth',1.1); % low --
hp1(k1,3)=plot(ax1,[.5+x(k1) .5+x(k1)],[lows(k1) highs(k1)],'Color',col_stick,'LineWidth',1.1); % the actual stick
hpt=[hpt; hp1];
end
hpt(1,:)=[];
end
and plot_bars
function [hpt]=plot_bars(ax1,x,highs,lows,opens,closes,col_down,sh,col_up)
% plot_bar plots high-low bars on supplied data
% input checks
% make sure x has no gaps and same interval
% make sure all lengths are the same :x highs lows opens closes
middle=sh.middle
hwbody=sh.hwbody
hwshad=sh.hwshad
xbody=sh.xbody
xshad=sh.xshad
npoints=length(x);
colors=closes<opens;
colors=char(colors*col_down+(1-colors)*col_up); % 'k' black 'w' white 'r' red 'b' blue or custom RGB [r g b] range [0 1]
% h1=figure(1)
hpt=[];
for k1=1:npoints
hp1=patch(ax1,x(k1)+xbody,[opens(k1),opens(k1),closes(k1),closes(k1),opens(k1)],colors(k1));
hpt=[hpt hp1];
end
end
This is the TEST SCRIPT HERE :
close all;clear all;clc
% opns : opens clos : closes , avoiding var names too close to reserved names
col_down='r'
col_up='r'
col_stick='k'
% this is to avoid having to make changes inside each function
sh.middle=0.5;
sh.hwbody=sh.middle/2;
sh.hwshad=sh.hwbody/10;
sh.xbody=sh.middle+[-sh.hwbody sh.hwbody sh.hwbody -sh.hwbody -sh.hwbody];
sh.xshad=sh.middle+[-sh.hwshad sh.hwshad sh.hwshad -sh.hwshad -sh.hwshad];
% time reference
npoints=15 % amount CONSECUTIVE days
x=[1:npoints] % day points
% data
y_mean0=50 % DC to avoid graph 002
y=rand(npoints,1)-0.5
opns=y_mean0+cumsum(y)
highs=opns+rand(npoints,1)
lows=opns-rand(npoints,1)
clos=opns+(highs-lows).*(rand(npoints,1)-0.5)
% plot frame
h1=figure(1)
ax1=gca
plot(ax1,[x(1)-1 x(end)+1],[y_mean0 y_mean0])
hold(ax1,'on')
plot(ax1,x,zeros(1,numel(x))+y_mean0,'|','Color',[.7 .7 .7]) % days reference
% plot data spans
hp1=plot_tees(ax1,x,highs,lows,opns,clos,sh,col_stick);
hold on
grid on; % off | minor
hp2=plot_bars(ax1,x,highs,lows,opns,clos,col_down,sh,col_up);
% include text tags
prec=7 % precision : amount total digits into string '.' not a digit
str_highs=num2str(highs,prec);
str_lows=num2str(lows,prec);
tr1=2 % trim, in case needed : how many decimal digits to drop from right hand side
str_highs(:,[end-tr1+1:end])=[];
str_lows(:,[end-tr1+1:end])=[];
% PENDING
% figure properties
h1.Name='graph 01';
h1.NumberTitle='off';
h1.ToolBar='auto'; % none | figure
h1.MenuBar='figure'; % | figure
h1.Color=[.7 .7 .7]; % figure background colour
ax1.Color=[.9 .9 .9]
% T-marker properties : modify T-marker properties here
for k1=1:1:size(hp1,1)
for k2=1:1:size(hp1,2)
hp1(k1,k2).LineWidth=1.1;
hp1(k1,k2).Color=[.9 .5 .3];
end
end
% bars properties : modify bar properties here
for k1=1:1:size(hp2,2)
hp2(k1).EdgeColor='none';
end
% plot aditional graphs
plot(ax1,x+.5,opns,'c','LineWidth',1.5)
5.- I am not using the data you supplied in the question. Instead I use randomly generated points.
You should have no trouble in replacing the random data with your data.
Let me know if any handicap.
5.1.- The time reference you supplied doesn't seem to match the supplied values; x has doubled values and there are more values than days
5.2.- The mean value hardly ever is exactly the average between each high and each low
5.3.- Using the data I know I could show how to do things like changing properties and including additional graphs, because with a clear time reference is available.
6.- Because you may need to change colours, bars opacity, bars edge, bars presence, and thickness of any, as well as there may be need to turn on/off each text field on graph (of each point and of all points) all handles to properties are now available.
Additional Comments :
7.- MATLAB built-in colours handy here
And some other commonly used custom colours
Any colour is available, just specify the RGB as vector [1 1 1] range of each element [0 1] 0: black, 1: white.
8.- MATLAB built-in markers are : arrow (default) ibeam crosshair watch topl botr circle cross fleur left right top bottom and hand.
One can also create custom pointers setting up figure property PointerShapeCData.
But none of these pointers are useful here because they are all 16x16 only, size matters.
This is why I asked in first place if the Ts had to be same size, or more reasonably, like in financial/investment/banking graphs you asked for T-markers proportional to the specified span, for each point.
9.- This question-answer has nothing to do with what is commonly known as T-graphs : 2 lists side by side to compare features.
10.- use uifigure instead of figure if you are building your app with App Builder.
I have sequence of data in MATLAB: data1, data2, data3,.... I want to print them one after one. I am stuck on that.
clear; clc;
data1=[1,2];
data2=[3,4];
n=[1,2];
for i=1:length(n)
fname(i,:)=sprintf('data%d',n(i));
end
Does this work for you?
clear; clc;
data1=[1,2];
data2=[3,4];
n=[1,2];
for i=1:length(n)
eval(['data' num2str(n(i))])
end
A possible solution not involving the use of eval could be the following.
Basically it consists of the following steps:
Get the list of data in the Workspace (with who function)
Identify the data to be printed (using regexp to identfy the variables names of the form dataxwhere x is a number)
save these variables in a temporary .mat file
load the .mat file in a struct which allows to have only the variables to be printed
exploit the dynamic field names to get access to the variables
This the code:
% Define some data
data1=[1,2];
data2=[3,4];
data3=rand(5)
data4a=rand(5)
dataaaa3=rand(5)
var_1=1
b=2
% Get the list of data in the Workspace
str=who
% Identify the data to be printed
var_to_print=regexp(str,'data\d$')
idx=~cellfun(#isempty,var_to_print)
% Down select the variables to be printed
str{idx}
% Generate a temporary ".mat" filename
tmp_name=[tempname '.mat']
% Save the data to be printed in the temporary ".mat" file
save(tmp_name,str{idx})
% Load the data to be printed into a struct
v=load(tmp_name)
% Get the names of the varaibles to be printed
f_name=fieldnames(v)
% print the value of the variables
for i=1:length(f_name)
[char(f_name(i)) ' = ']
v.(f_name{i})
end
% Move the temporary ".mat" file in the recycle folder
recycle('on')
delete(tmp_name)
Hope this helps.
Qapla'
I want to create a frontend where the user can browse pictures forward by pressing Enter.
Pseudo-Code
hFig=figure
nFrames=5;
k=1;
while k < nFrames
u=signal(1*k,100*k,'data.wav'); % 100 length
subplot(2,2,1);
plot(u);
subplot(2,2,2);
plot(sin(u));
subplot(2,2,3);
plot(cos(u));
subplot(2,2,4);
plot(tan(u));
% not necessary but for heading of overal figure
fprintf('Press Enter for next slice\n');
str=sprintf('Slice %d', k);
mtit(hFig, str);
k=k+1;
keyboard
end
function u=signal(a,b,file)
[fs,smplrt]=audioread(file);
u=fs(a:b,1);
end
where
something is wrong in updating the data because pressing CMD+Enter increases k by one but does not update the data. Sometimes (rarely), the data is once the next iteration.
something is wrong with while's condition because k can be bigger than nFrames. keyboard just keep asking for more inputs.
My mistake earlier in Error-Checking
I had earlier a problem where the closure of the window lead to the crash of the application. I include this here because I mentioned a problem about it in the comment of one answer. I avoid the problem now by
hFig=figure;
n=5;
k=1;
while k<nFrames
% for the case, the user closes the window but starts new iteration
if(not(ishandle(hFig)))
hFig=figure;
end
...
end
which creates a new Figure if the earlier was closed by the user.
I tried unsuccessfully putting hFig=figure; inside the while loop's if clause earlier to avoid repetition in the code.
Please, let me know if you know why you cannot have the handle hFig in the while loop's if clause.
How can you loop subplots with updated outputs in Matlab?
To stop the script waiting for an input from the user you should use input instead of keyboard.
Actually keyboard makes your script entering in a debug mode. It stops the executino of the script as (like a breakpoint) allowing the user to, for example, check the value of a variable.
You can modify your scripr as follows (modification are at the end of your script, identified by "UPDATED SECTION):
hFig=figure
nFrames=5;
k=1;
while k < nFrames
u=signal(1*k,100*k,'handel.wav'); % 100 length
subplot(2,2,1);
plot(u);
subplot(2,2,2);
plot(sin(u));
subplot(2,2,3);
plot(cos(u));
subplot(2,2,4);
plot(tan(u));
% not necessary but for heading of overal figure
%
% UPDATED SECTION
%
% Use the string "Press Enter for next slice\n" as the prompt for the
% call to "input"
%
% fprintf('Press Enter for next slice\n');
% str=sprintf('Slice %f', k);
% Use %d instead of "%f" to print integer data
str=sprintf('Slice %d', k);
mtit(hFig, str);
k=k+1;
% Use "input" instead of "keyboard"
% keyboard
input('Press Enter for next slice\n')
end
Hope this helps.
Qapla'
When using the Publish feature of MATLAB, it typically publishes only what comes after the % signs or the function output. However, is there any command to take a variable and splice its value into text, possibly even creating LaTeX formulae from a MATLAB variable that holds a character string?
Here is an example of rendering LaTeX formulae (one hard-coded in comments, other stored as a string in a variable).
%% LaTeX Examples
% Below are some equations rendered in LaTeX.
% (try to publish this file).
%
%% The definition of e
% Here we use equation embedded in the file.
%
% $$ e = \sum_{k=0}^\infty {1 \over {k!} } $$
%
%% The Laplace transform
% Here we render an equation stored in a variable.
%
% offscreen figure
fig = figure('Menubar','none', 'Color','white', ...
'Units','inches', 'Position',[100 100 6 1.5]);
axis off
str = 'L\{f(t)\} \equiv F(s) = \int_0^\infty\!\!{e^{-st}f(t)dt}';
text(0.5, 0.5, ['$$' str '$$'], 'Interpreter','latex', 'FontSize',28, ...
'HorizontalAlignment','center', 'VerticalAlignment','middle')
snapnow
close(fig);
Here is how it looks like when the file is published as HTML:
You could wrap that last code in a helper function render_latex_string(str) and call it from different places.
To use variables from the workspace
when Publishing to html using disp() with a html encoded string will add the lines to the output (without using the formatting for code output).
for example
str = sprintf('some value: %f from the workspace',variable)
disp(['<html>',str,'</html>'])
Notes:
It is quite sensitive and you may need to add invisible section breaks between
code output and lines produced in this way.
Adding paragraph tags is useful to improve formatting
Sadly (to my knowledge) the publishing markdown interpreter is not used on these lines, they are "injected" into the output, therefore latex equations will not work.
Code
%% HTML option
% This option is anly available with HTML output...
a=1;
str = ['The current value of a is ', num2str(a)];
%%%
%
% When publishing to HTML using the |disp| function with HTML tags
% surrounding the string can allow workspace variables to appear within
% text.
%
% For example the following line is created by evaluating code, it is not a
% comment in the m-file
%
disp(['<html><p>',str,'</p></html>']);
%% Changing the value
% Now if we change a to 2...
a=2,str = ['The new value of a is ', num2str(a)];
%%
% Re-runing a similar code should show the updated value
disp(['<html><p>',str,'</p></html>'])
Output
The code above generates the following:
clc
clear all
ii=1;
S =cell(size(30,1)); % cell size.
for ii=1:1:3
rand_id= rand(1,1) *3; % Randomly generte a number between 1 to 3.
if (rand_id<1)
rand_id=1; % 0 is ommitted.
else rand_id=floor(rand_id);
end
% rand_id will be used to open a previously saved file randomly.
if (rand_id==1)
f_id_1=fopen('C1.txt','r'); % Open and read a file.
elseif (rand_id==2)
f_id_1=fopen('C2.txt','r'); % Open and read a file.
end
% saning the file to read the text.
events_1=textscan(f_id_1, '%s', 'Delimiter', '\n');
fclose(f_id_1);
events_1=events_1{1}; % saving the text.
rand_event=events_1{randi(numel(events_1))}; % selects one text randomly.
S{ii}=rand_event;
end
I wrote the above code to randomly select a file. The file contains number of sentences. My aim is to randomly pick a sentence . I did that. Now, my problem is I cant save all the picked sentences inside the loop.
When I declare S(ii)=rand_event It shows error. When I try S(ii)=rand_event(ii) It only returns 1, 2, 3 characters in the three loops.
Please help.
S(ii)
is considered to be a matrix with well defined dimensions. I guess that your 'sentences' have different length. One solution might be to use a cell array.
S{ii}=rand_event
Cell arrays use curly braces.