Difficulty printing all 6 of my matlab figures to PDF (Matlab) - matlab

I've got a script I've been working on that publishes figures I create into power point, consecutively. Each figure that is created is assigned a figure handle in the previous script. However, when I try to print each figure into a pdf, it will only return a copy of the PDF with my final figure handle (FH6). How can i get this script to print each figure, FH1-FH6, into a single pdf or their own separate pdfs. Thank you for your time
Here is an example of what i have:
close all
clear
get_mlo_data
import mlreportgen.ppt.*;
slidesFile = 'mySlides_v1.pptx';
delete(slidesFile)
slides = Presentation(slidesFile);
slide1 = add(slides,'Title Slide');
replace(slide1,'Title','Research Presentation');
replace(slide1,'Subtitle','Author');
insertmyimage(fh1,slides,'CO2 Trends')
insertmyimage(fh2,slides,'Keeling Curve')
insertmyimage(fh3,slides,'Interpolated Vs Trend')
insertmyimage(fh4,slides,'DOTS')
insertmyimage(fh5,slides,'Seasonal')
insertmyimage(fh6,slides,'Keeling Spiral')
please_god = get(groot, 'Children');
print('please_god','-dpdf')
close(slides);
function insertmyimage(FigureHandle,slides,FigureTitle)
import mlreportgen.ppt.*;
tempimgname = ['WayneImage' num2str(numel(slides.Children)+1) '.png'];
saveas(FigureHandle,tempimgname);
tempplot = Picture(tempimgname);
pictureSlide = add(slides,'Title and Content');
replace(pictureSlide,'Title',FigureTitle);
replace(pictureSlide,'Content',tempplot)
end

Related

how could I read multiple series in one xlsx file and save in .mat?

First sorry for basic questions..
What I've done was importing ".csv" to matlab using "readtable. But I don't have idea as to making this 367 different time series to be independent .mat files.
result = readtable('price.csv');
result is shown in image file to help understanding..
How could I make this process automatically?? Please help me..
result = readtable('price.csv');
for i = 1:2:734
M = rmmissing(result(:,[i,i+1]));
str = M.Properties.VariableNames(2);
% str{1}(regexp(str{1}, 'x')) = [];
name = str{1};
save(['C:\Users\bok\Desktop\mat\',name],'M');
end

How can I run a MATLAB script on .csv files in two separate folders at the same time?

So I have an iterative loop that extracts data from .csv files in MATLAB's active folder and plots it. I would like to take it one step further and run the script on two folders, each with their own .csv files.
One folder is called stress and the other strain. As the name implies, they contain .csv files for stress and strain data for several samples, each of which is called E3-01, E3-02, E3-03, etc. In other words, both folders have the same number of files and the same names.
The way I see it, the process would have the following steps:
Look in the stress folder, look inside file E3-01, extract the data in the column labelled Stress
Look in the strain folder, look inside file E3-01, extract the data in the column labelled Strain
Combine the data together for sample E3-01 and plot it
Repeat steps 1-3 for all files in the folders
Like I said, I already have a script that can find the right column and extract the data. What I'm not sure about is how to tell MATLAB to alternate the folder that the script is being run on.
Instead of a script, would a function be better? Something that accepts 4 inputs: the names of the two folders and the columns to extract?
EDIT: Apologies, here's the code I have so far:
clearvars;
files = dir('*.csv');
prompt = {'Plot name:','x label:','y label:','x values:','y values:','Points to eliminate:'};
dlg_title = 'Input';
num_lines = 1;
defaultans = {'Title','x label','y label','Surface component 1.avg(epsY) [True strain]','Stress','0'};
answer = inputdlg(prompt,dlg_title,num_lines,defaultans);
name_plot = answer{1};
x_label = answer{2};
y_label = answer{3};
x_col = answer{4};
y_col = answer{5};
des_cols = {y_col,x_col};
smallest_n = 100000;
points_elim = answer{6};
avg_x_values = [];
avg_y_values = [];
for file = files'
M=xlsread(file.name);
[row,col]=size(M);
if smallest_n > row
smallest_n = row;
end
end
smallest_n=smallest_n-points_elim;
avg_x_values = zeros(smallest_n,size(files,1));
avg_y_values = zeros(smallest_n,size(files,1));
hold on;
set(groot, 'DefaultLegendInterpreter', 'none');
set(gca,'FontSize',20);
ii = 0;
for file = files'
ii = ii + 1;
[n,s,r] = xlsread(file.name);
colhdrs = s(1,:);
[row, col] = find(strcmpi(s,x_col));
x_values = n(1:end-points_elim,col);
[row, col] = find(strcmpi(s,y_col));
y_values = n(1:end-points_elim,col);
plot(x_values,y_values,'DisplayName',s{1,1});
avg_x_values(:,ii)=x_values(1:smallest_n);
avg_y_values(:,ii)=y_values(1:smallest_n);
end
ylabel({y_label});
xlabel({x_label});
title({name_plot});
colormap(gray);
hold off;
avg_x_values = mean(avg_x_values,2);
avg_y_values = mean(avg_y_values,2);
plot(avg_x_values,avg_y_values);
set(gca,'FontSize',20);
ylabel({y_label});
xlabel({x_label});
title({name_plot});
EDIT 2: #Adriaan I tried to write the following function to get a column from a file:
function [out_col] = getcolumn(col,file)
file = dir(file);
[n,s,r] = xlsread(file.name);
colhdrs = s(1,:);
[row, col] = find(strcmpi(s,col));
out_col = n(1:end,col);
end
but I get the error
Function 'subsindex' is not defined for values of class 'struct'.
Error in getcolumn (line 21)
y = x(:,n);
not sure why.
You can do both, of course, and it depends on preference mainly, provided you're the sole user of the script. If others are going to use it as well, use functions instead, as they can contain a proper help file and calling help functionname will then give you that help.
For instance:
folders1 = dir(../strain/*)
folders2 = dir(../stress/*)
for ii 1 = 1:numel(folders)
operand1 = folders1{ii};
operand2 = folders2{ii};
%... rest of script
%
% Or function:
data = YourFunction(folders1{ii},folders2{ii})
end
So all in all you can use both, although from experience I find functions easier to use in the end, as you just pass parameters and don't need to trawl through the complete code to change the parameters each run.
Additionally you can partition off small parts of your program which do a fix task. If you nest your functions, and finally call just a single function in your scripts, you don't have to look at hundreds of lines of code each time you run the script, but rather can just run a single function (which can also be inside a script or function, ad infinitum).
Finally, a function has its own scope; meaning that any variables that are in that function stay within that function unless you explicitly set them as output (apart from global variables, but those are problematic anyway). This can be a good thing, or a bad thing, depending on the rest of your code. If you function would output ~20 variables for further processing, the function probably should include more steps. It'd be a good thing if you create lots of intermediate variables (I always do), because when the function's finished running, the scope of that function will be removed from memory, saving you clear tmpVar1 tmpVar2 tmpVar3 etc every few lines in your script.
For the script the argument in favour would be that it is easier to debug; you don't need dbstop on error and can step a bit easier through the script, keeping check of all your variables. But, after the debugging has been completed, this argument becomes moot, and thus in general I'd start with writing a script, and once it performs as desired, I rework it to a function at minimal extra effort.

pngwritec error in Matlab 2017b

The pngwritec function is at the core of my program, but however, I get a series of errors when I run my main file.
Error using pngwritec
PNG library failed: Write Error.
There does not seem to be any documentation available online, yet somehow, when I ran the same program a couple of days ago, there was no issue. Is this a side effect of some new Matlab update? I'm using Matlab 2017b.
Edit:
The error shows up at the first time I need to convert an image to PNG using imwrite.
if (~exist(fullfile(denoiseFolder, [nameF '_d' extF]), 'file') | overwrite)
if saveWaveletCoeffs
waveletFileName = fullfile(saveWaveletFolder, [nameF '_w.mat']);
else
waveletFileName = '';
end
imIn = imread(fileName);
imOut = waveletDenoise(imIn, sigma0, waveletFileName);
imOut = uint8(round(imOut));
fileName = fullfile(denoiseFolder, [nameF '_d' extF]);
imwrite(imOut, fileName, 'png'); %Error here
end

for loop+structure allocation in matlab

This is a problem I am working on in Matlab.
I am looping through a series of *.ALL files and stripping the field name by a delimiter '.'. The first field is the network, second station name, third location code and fourth component. I pre-allocate my structure based on the number of files (3) I run through which for this example is a 3x3x3 structure that I would like to define as struct(station,loc code,component). You can see these definitions in my code example below.
I would like to loop through the station, loc code, and component and fill their values in the structure. The only problem is for some reason the way I've defined the loop it's actually looping through the files more than once. I only want to loop through each file once and extract the station, comp, and loc code from it and put it inside the structure. Because it's looping through the files more than once it's taken like 10 minutes to fill the structure. This is not very efficient at all. Can someone point out the culprit line for me or tell me what I'm doing incorrectly?
Here's my code below:
close all;
clear;
[files]=dir('*.ALL');
for i = 1:length(files)
fields=textscan(files(i).name, '%s', 'Delimiter', '.');
net{i,1}=fields{1}{:};
sta{i,1}=fields{1}{2};
loc{i,1}=fields{1}{3};
comp{i,1}=fields{1}{4};
data = [];
halfhour(1:2) = struct('data',data);
hour(1:24) = struct('halfhour',halfhour);
day(1:366) = struct('hour',hour);
PSD_YE_DBT(1:length(files),1:length(files),1:length(files)) =
struct('sta','','loc','','comp','','allData',[],'day',day);
end
for s=1:1:length(sta)
for l=1:1:length(loc)
for c=1:1:length(comp)
tempFileName = strcat(net{s},'.',sta{s},'.',loc{l},'.',comp{c},'.','ALL');
fid = fopen(tempFileName);
PSD_YE_DBT(s,l,c).sta = sta{s};
PSD_YE_DBT(s,l,c).loc = loc{l};
PSD_YE_DBT(s,l,c).comp = comp{c};
end
end
end
Example file names for the three files I'm working with are:
XO.GRUT.--.HHE.ALL
XO.GRUT.--.HHN.ALL
XO.GRUT.--.HHZ.ALL
Thanks in advance!

How to export data from Matlab to excel for a loop?

I have a code for "for loop"
for i=1:4
statement...
y=sim(net, I);
end
now i need to export the value of y to excel sheet. for that i used..
xlswrite('output_data.xls', y, 'output_data', 'A1')
but my problem is that the ID of excel i.e. "A1" should change according to each iteration... in my case for iteration 1-> A1, iteration-> A2 and so on..
anybody please help me out ..
thanks in advance. for any assistance.. or suggestion..
You can store sim outputs in a vector (y(ii)) and save in the sheet with a single write. This is also more efficient since you perform a single bulk-write instead of many small writes.
Specify the first cell and y will be written starting from there.
last = someNumber;
for i=1:last statement... y(i)=sim(net, I); end
xlswrite('output_data.xls', y', 'output_data', 'A1');
If you prefer specify the range write ['A1:A',num2str(last)] instead of A1.
If you really want to write within the loop try:
for ii=1:last
...
y=sim(net, I);
xlswrite('output_data.xls', y, 'output_data', sprintf('A%d',ii));
end
You can also do for yourself what xlswrite does internally, which is interact using COM. I prefer to do this when I have a frequently used excel template or data file, because it allows for more control (albeit with more lines of code).
Excel = actxserver('Excel.Application');
Workbook = Excel.Workbooks.Open('myExcelFile.xlsx');
MySheet = Excel.ActiveWorkBook.Sheets.Item(1);
set( get(MySheet,'Range','A1:A10'), 'Value', yourValues);
...
invoke(Workbook, 'Save');
invoke(Excel, 'Quit');
delete(Excel);
This would allow you to save new data to new ranges without re-opening excel each time.
Even better would be to define an oncleanup function (as does xlswrite) to prevent lost file locks (especially when you're doing things like exiting out of debug mode):
...
myWorkbook = Excel.Workbooks.Open(filename,0,true);
cleanUp = onCleanup(#()xlsCleanup(Excel, filename));
function xlsCleanup(Excel,filepath)
try
Excel.DisplayAlerts = 0; %// Turn off dialog boxes
[~,n,e] = fileparts(filepath); %// Excel API expects just the filename
fileName = [n,e];
Excel.Workbooks.Item(fileName).Close(false);
end
Excel.Quit;
end
You can put xlswrite after for loop.You just want to do is save you result in a matrix.This function can write a matrix.
also,you can use [] to combine string to change the range.
>> for i=1:4
Range=['A' num2str(i)]
end
Range =
A1
Range =
A2
Range =
A3
Range =
A4
But,this is a bad way.You should open and write Excel file every time.