Cannot use scatterplot in Octave - matrix

I was learning how to do machine learning on mldata.org and I was watching a video on Youtube on how to use the data (https://www.youtube.com/watch?v=zY0UhXPy8fM) (2:50). Using the same data, I tried to follow exactly what he did and create a scatterplot of the dataset. However when he used the scatterplot command, it worked perfectly on his side, but I cannot do it on myside.
Can anyone explain what's wrong and what I should do?
octave:2> load banana_data.octave
octave:3> pkg load communications
octave:4> whos
Variables in the current scope:
Attr Name Size Bytes Class
==== ==== ==== ===== =====
data 2x5300 84800 double
label 1x5300 42400 double
Total is 15900 elements using 127200 bytes
octave:5> scatterplot(data, label)
error: scatterplot: real X must be a vector or a 2-column matrix
error: called from:
error: /home/anthony/octave/communications-1.2.0/scatterplot.m at line 69, column 7

The error message says it all. Your data is a 2-row matrix, and not a 2-column matrix as it should be. Just transpose it with .'.
scatterplot(data.')
I dropped the label argument since it is not compatible with the communications toolbox, either in matlab or in octave.
Update:
According to news('communications'),
The plotting functions eyediagram' andscatterplot' have improved Matlab compatibility
This may be why the behaviour is different. Be ready to find other glitches, as the octave 3.2.4 used in this course is about 5 years old.
In order to use the label, you should rather use the standard octave scatter function.
Colors could be changed by choosing another colormap.
colormap(cool(256))
scatter(data(1,:), data(2,:), 6, label, "filled")

Related

View full contents of a matrix in Euler Math Toolbox

How to display all the numbers from a given matrix in Euler Math Toolbox? It doesn't seem to show more than 8 columns at a time, which isn't enough as I frequently need to view more than that.
Output I'm getting as of now:
The documentation says:
Large matrices or vectors might not print in full size. To change this, toggle the behavior with:
largematrices on
largematrices off
or use the operator showlarge.
showlarge random(10,10)
See:
showlarge (Basic Utilities)
The link in the above documentation link directs here:
function prefix showlarge (x$)
Prints large matrices in full.
By default EMT eclipses lines and rows of large matrices. This can be used to see the full matrix. If the parameter is a variable the variable name will be printed.
The default can be changed with largematrices on/off.
x=random(20,5); showlarge(x)
showlarge(random(20,5))
See:
largematrices (Euler Core),
show (Maxima Documentation)

Save a figure to file with specific resolution

In an old version of my code, I used to do a hardcopy() with a given resolution, ie:
frame = hardcopy(figHandle, ['-d' renderer], ['-r' num2str(round(pixelsperinch))]);
For reference, hardcopy saves a figure window to file.
Then I would typically perform:
ZZ = rgb2gray(frame) < 255/2;
se = strel('disk',diskSize);
ZZ2 = imdilate(ZZ,se); %perform dilation.
Surface = bwarea(ZZ2); %get estimated surface (in pixels)
This worked until I switched to Matlab 2017, in which the hardcopy() function is deprecated and we are left with the print() function instead.
I am unable to extract the data from figure handler at a specific resolution using print. I've tried many things, including:
frame = print(figHandle, '-opengl', strcat('-r',num2str(round(pixelsperinch))));
But it doesn't work. How can I overcome this?
EDIT
I don't want to 'save' nor create a figure file, my aim is to extract the data from the figure in order to mesure a surface after a dilation process. I just want to keep this information and since 'im processing a LOT of different trajectories (total is approx. 1e7 trajectories), i don't want to save each file to disk (this is costly, time execution speaking). I'm running this code on a remote server (without a graphic card).
The issue I'm struggling with is: "One or more output arguments not assigned during call to "varargout"."
getframe() does not allow for setting a specific resolution (it uses current resolution instead as far as I know)
EDIT2
Ok, figured out how to do, you need to pass the '-RGBImage' argument like this:
frame = print(figHandle, ['-' renderer], ['-r' num2str(round(pixelsperinch))], '-RGBImage');
it also accept custom resolution and renderer as specified in the documentation.
I think you must specify formattype too (-dtiff in my case). I've tried this in Matlab 2016b with no problem:
print(figHandle,'-dtiff', '-opengl', '-r600', 'nameofmyfig');
EDIT:
If you need the CData just find the handle of the corresponding axes and get its CData
f = findobj('Tag','mytag')
Then depending on your matlab version use:
mycdata = get(f,'CData');
or directly
mycdta = f.CData;
EDIT 2:
You can set the tag of your image programatically and then do what I said previously:
a = imshow('peppers.png');
set(a,'Tag','mytag');

can't determine number of catergories in trainImageCategoryClassifier in matlab

Doing this example in Matlab Image Category Classification I have found an error trying to encode an image into a feature vector.
categoryClassifier = trainImageCategoryClassifier(trainingSet, bag);
Error using imageCategoryClassifier (line 436)
You need at least two image categories. That means that the number of elements in input array of imageSet
objects, imSets, must be at least two.
Error in imageCategoryClassifier.create (line 328)
this = imageCategoryClassifier(imgSet, bag, varargin{:});
Error in trainImageCategoryClassifier (line 82)
classifier = imageCategoryClassifier.create(imgSet, bag, varargin{:});
i have 3 categories But it says i have one category in trainingSet. what should i do?!
Which version of MATLAB are you using? This documentation is for the 2017a version. If you have an older version then running this code from the document gives you a 3x1 vector of categories.That is why the classifier treats it as one category.For 3 categories you'll need a 1x3 vector.
You can go to the command window and open the reference page on imageCategoryClassifier or on bagOfFeatures.This will give you the documentation of the version that you're running. There'll also be a link for the example MATLAB program. That's what worked for me.
Hope this helps!

Converting images from RGB to HSL and back again with julia

I have been trying to open some RGB images, view the data as a 2D array of HSL pixels, manipulate pixels in HSL space, convert back to RGB and write manipulated image to file. However I don't quite understand how the conversions in the (awesome) julia packages Color and Images work.
For example, I expect the code below (partially written following the example from this SO question) to write something very much like this image file (as test_1.png and test_2.png):
However, the code below actually produces this much darker image instead:
How should I re-arrange the arrays or images to get the output I expect?
using Color, Images
# Download file, read it in, convert colourspace to HSL and recast as array
fname=download("https://farm9.staticflickr.com/8725/17074451907_2381037c7d_m_d.jpg")
rgb=imread(fname)
hsl=convert(Image{HSL},float32(rgb))
hslArr=reinterpret(data(hsl))
# I would like to manipulate HSL data here...
# Two ways to convert manipulated array back to HSL image
hsl_1=Image(hslArr; colorspace="HSL", colordim=1, spatialorder=["x","y"])
hsl_2=reinterpret(HSL{Float32},hslArr)
# Two ways to convert HSL image to RGB image
rgb_1=convert(Image{RGB},hsl_1)
rgb_2=convert(Array{RGB{Float32}},hsl_2)
# Finally, write images to file
imwrite(rgb_1,"test_1.png")
imwrite(rgb_2,"test_2.png")
UPDATE
Thanks to #rickhg12hs finding bug in the Color.jl module, I get expected output from code above after the following steps:
Fork the source repository for Color.jl on github
Correct the conversion function (as below), pushing changes to my fork of Color.jl
Remove the default Color.jl module that comes with julia
Install my forked package using Julia's git mechanism.
Restart julia
I haven't been able to figure out how to install a forked version of a module in parallel with a previous version, but executing the following (followed by restarting julia) should temporarily fix the bug:
Pkg.rm("Color")
Pkg.clone("https://github.com/CnrLwlss/Color.jl.git","Color")
Pkg.checkout("Color","master")
Will need to switch back to original Color module once pull request goes through.
Until Color.jl gets updated and more testing implemented/passed, you can make a single character change in Color/src/conversions.jl to most likely fix this particular issue. Change - to + on line 156.
150 # Everything to HSL
151 # -----------------
152
153 function convert{T}(::Type{HSL{T}}, c::AbstractRGB)
154 c_min = min(c.r, c.g, c.b)
155 c_max = max(c.r, c.g, c.b)
156 l = (c_max + c_min) / 2 # <-- Changed '-' to '+'
On my machine, your HSL converted bird looks great now!

Creating animation with multiple plots in Octave

I'm using Octave to write a script that plots a function at different time periods. I was hoping to create an animation of the plots in order to see the changes through time.
Is there a way to save each plot for each time point, so that all plots can be combined to create this animation?
It's a bit of kludge, but you can do the following (works here with octave 4.0.0-rc2):
x = (-5:.1:5);
for p = 1:5
plot (x, x.^p)
print animation.pdf -append
endfor
im = imread ("animation.pdf", "Index", "all");
imwrite (im, "animation.gif", "DelayTime", .5)
Basically, print all your plots into a pdf, one per page. Then read the pdf's as images and print them back as gifs. This will not work on Matlab (its imread implementation can't handle pdf).
This creates an animated gif
data=rand(100,100,20); %100 by 100 and 20 frames
%data go from 0 to 1, so lets convert to 8 bit unsigned integers for saving
data=data*2^8;
data=uint8(data);
%Write the first frame to a file named animGif.gif
imwrite(data(:,:,1),'/tmp/animGif.gif','gif','writemode','overwrite',...
'LoopCount',inf,'DelayTime',0);
%Loop through and write the rest of the frames
for ii=2:size(data,3)
imwrite(data(:,:,ii),'/tmp/animGif.gif','gif','writemode','append','DelayTime',0)
end
Had to come chime in here because this was the top Google result for me when I was looking for help with this. I had issues with both answers, and some other issues, too. Notably:
For Rick T's answer, the code snippet doesn't write a plot figure, it just writes matrix data. Getting the plot window was a pain.
For carandraug's answer, writing to a PDF took a very long time and made a gigantic PDF.
On my own machine, I'm pretty sure I used apt-install to get Octave, but the getframe function I found referenced in other answers wasn't found. Turns out I had installed version 4.4, which was from 2018 (>3 years old).
I removed the old version of Octave sudo apt remove octave, then installed the new version with snap. If you try octave from a terminal without it installed it should prompt you to the snap install - be sure to include the # 6.4.0 or whatever is included in the command.
Once I had the current version installed, I got access to the getframe command, which is what lets you convert directly from a figure handle to image data - this bypasses the hackey (but previously necessary step) in #carandraug's answer where you had to write to PDF or some other image as a placeholder.
I used #RickT's answer to make my own MakeGif function, which I will share with you all here. Note that MakeGif stores the filename in a persistent variable, meaning it is retained across calls. If you change the filename it will make (or overwrite!!) the new file. If you need to overwrite the current file (i.e., running the same script multiple times and want new results) then you can use clear MakeGif between calls and that will reset the persistentFilename.
Here is the code for the MakeGif function; code to test it with is provided after this:
function MakeGif(figHandle, filename)
persistent persistentFilename = [];
if isempty(filename)
error('Can''t have an empty filename!');
endif
if ~ishandle(figHandle)
error('Call MakeGif(figHandle, filename); no valid figHandle was passed!');
endif
writeMode = 'Append';
if isempty(persistentFilename)|(filename!=persistentFilename)
persistentFilename = filename;
writeMode = 'Overwrite';
endif
imstruct = getframe(figHandle);
imwrite(imstruct.cdata, filename, 'gif', 'WriteMode',writeMode,'DelayTime',0);
endfunction
And here is the code to test the function. There's a commented-out call to clear MakeGif between the blue and green colors. If you leave it commented out it will append the green sine wave to the blue sine wave, resulting in alternating colors after every cycle - again the filename is persistent in the function. If you uncomment that call then the MakeGif function will treat the green's call as "new" and trigger the overwrite of the blue sine wave and all you'll see is green.
clear all;
time = 0:0.1:2*pi;
nSamples = numel(time);
figHandle = figure(1);
for i=1:nSamples
plot(time,sin(time + time(i)),'Color','blue');
drawnow;
MakeGif(figHandle, 'test.gif');
endfor
% Uncomment the 'clear' command below to clear the MakeGif persistent
% memory, which will trigger the green sine wave to overwrite the blue.
% Default behavior is to APPEND a green sine wave because the filename
% is the same.
%clear MakeGif;
for i=1:nSamples
plot(time,sin(time + time(i)),'Color','green');
drawnow;
MakeGif(figHandle, 'test.gif');
endfor
I spent several hours on this after being super dissatisfied with laggy screen captures so I really hope this helps someone in the future! Good luck and best wishes from the Age of Covid lol.
#Chuck thanks for that code; I've been using it to save 1500-frame GIFs of simulation output, and I find that after maybe ~500 frames the time to save the next frame to the output during the call to MakeGif starts to become ... unnerving. I guess imwrite reads and writes the entirety of the output file at each call that includes the 'WriteMode','Append' pair. At frame 1500 my output is 480Mb so that becomes untenable.
An apparent rescue for this is hinted at in the doc for Octave 7.1.0's imwrite, with the suggestion that you can pass it a 4-dimensional array and write the entire image sequence with one call. I haven't been able to make this work, though: Calling imwrite that way seems to simply write the very first image in the sequence into every frame in the output file.

Resources