Related
I have different folders with datasets called e.g.
3-1-1
3-1-2
3-2-1
3-1-2
the first placeholder is fixed, the second and third are elements of a list:
k1values = "1 2"
k2values = "1 2"
I want to do easy operations in my Gnuplot script e.g. cd to the above directories and read a line of a textfile. First, it shall cd to the folder, read a file and cd back again etc.
My first (1) idea was to connect system command and sprintf:
do for[i=1:words(k1values)]{
do for[j=1:words(k2values)]{
system sprintf("cd 3-%d-%d", i, j)
system 'pwd'
system 'cd ..'
}
}
with that the same path is being printed, so no CD is happening at all.
or system 'cd sprintf("3-%d-%d", i, j)'
Unfortunately, this is not working.
Error message: sh: 1: Syntax error: "(" unexpected
I also tried concatenating the values to a string and enter it as a path: This also doesn't work:
k1values = "1 2"
k2values = "1 2"
string1 = '3'
do for[i=1:words(k1values)]{
do for[j=1:words(k2values)]{
path = sprintf("%s-%d-%d", string1, i, j)
system sprintf("cd %s", path)
system 'pwd'
system 'cd ..'
}
}
I print the path for testing, but the operating path is not being changed at all.
Thanks in advance!
Edit: The idea in a given pseudo code is like this:
do for k1
do for k2
valueX = <readingCommand>
make dir "3-k1-k2/Pictures"
for int i = 0; i<valueX; i++
set output bla
plot "3-k1-k2/Data/i.txt" <options>
end for
end do for
end do for
Unless there is a reason which we don't know yet, why do you want to change back and forth into the subdirectories?
Why not creating your path/filename via a function and load the desired file and plot the desired lines?
For example, if you have the following directory structure:
CurrentFolder
3-1-1
Data.dat
3-1-2
Data.dat
3-2-1
Data.dat
3-2-2
Data.dat
and the following files:
3-1-1/Data.dat
1 1.14
2 1.15
3 1.12
4 1.11
5 1.13
3-1-2/Data.dat
1 1.24
2 1.25
3 1.22
4 1.21
5 1.23
3-2-1/Data.dat
1 2.14
2 2.15
3 2.12
4 2.11
5 2.13
3-2-2/Data.dat
1 2.24
2 2.25
3 2.22
4 2.21
5 2.23
The following example loads all the files Data.dat from the corresponding subdirectories and plots the lines 2 to 4 (the lines have 0-based index, check help every).
Script:
### plot specific lines from files from different directories
reset session
k1values = "1 2"
k2values = "1 2"
string1 = '3'
myPath(i,j) = sprintf("%s-%s-%s",string1,word(k1values,i),word(k2values,j))
myFile(i,j) = sprintf("%s/%s",myPath(i,j),"Data.dat")
set key out
plot for [i=1:words(k1values)] for[j=1:words(k2values)] myFile(i,j) \
u 1:2 every ::1::3 w lp pt 7 ti myPath(i,j)
### end of script
Result:
This is my final solution:
k1values = '0.5 1'
k2values = '0.5 1'
omega = 3
do for[i in k1values]{
do for[j in k2values]{
savingPoint = system('head -n 1 "3-'.i.'-'.j.'/<fileName>.dat" | tail -1')
number = savingPoint/<value>
do for[m = savingPoint:0:-<value>]{
set title <...>
set output <...>
plot ''.omega.'-'.i.'-'.j.'/Data/'.m.'.txt' <...>
}
}
}
<...> is a placeholder and irrelevant.
So this is how I finally iterate over the folders.
Within the second for loop, a reading command is executed and allocated to a variable which is needed in the third for loop. i and j are strings though, but that does not matter.
I'm trying to display an array as a figure in MATLAB using coloured textbox that varies according to the value at that location.
So far, I have tried to use the MATLAB Edit Plot Tool to draw such a figure and then generate the code to see what it might look like. Here is what I came up with:
figure1=figure
annotation(figure1,'textbox',...
[0.232125037302298 0.774079320113315 0.034810205908684 0.0410764872521246],...
'String','HIT',...
'FitBoxToText','off',...
'BackgroundColor',[0.470588235294118 0.670588235294118 0.188235294117647]);
annotation(figure1,'textbox',...
[0.27658937630558 0.774079320113315 0.034810205908684 0.0410764872521246],...
'String',{'STAY'},...
'FitBoxToText','off',...
'BackgroundColor',[1 0 0]);
Here the result does not look so good. I'd like something neat and not as hard to write. Visually, I'd like something like this:
I've found a possible solution using the pcolor function.
Warning: I've tested it only with Octave
If you want to create a (m x n) table with, as per your picture, 4 colour, you have to:
create an array with size (m+1 x n+1) of integers' in the1:4` range setting them according to the desired order
call pcolor to plot the table
adjust the size of the figure
create your own colormap according to the desired colors
set the `colormap'
add the desired text using the text function
set the tick and ticklabel of the axes
Edit to answer the comment
In the following you can find a possible implementation of the proposed solution.
The code creates two figure:
In the first one wil be ploted the values of the input matrix
In the second one the user defined strings
The association "color - value" is performed through the user-defined colormap.
Since in the matrix x there are 4 different possible values (it has been defined as x=randi([1 4],n_row+1,n_col+1);) the colormap has to consists of 4 RGB entry as follows.
cm=[1 0.3 0.3 % RED
0.3 0.3 1 % BLUE
0 1 0 % GREEN
1 1 1]; % WHITE
Should you want to change the association, you just have to change the order of the rows of the colormap.
The comments in the code should clarify the above steps.
Code updated
% Define a rnadom data set
n_row=24;
n_col=10;
x=randi([1 4],n_row+1,n_col+1);
for fig_idx=1:2
% Open two FIGURE
% In the first one wil be ploted the values of the input matrix
% In the second one the user defined strings
figure('position',[ 1057 210 606 686])
% Plot the matrix
s=pcolor(x);
set(s,'edgecolor','w','linewidth',3)
% Define the colormap
%cm=[1 1 1
% 0 1 0
% 0.3 0.3 1
% 1 0.3 0.3];
cm=[1 0.3 0.3 % RED
0.3 0.3 1 % BLUE
0 1 0 % GREEN
1 1 1]; % WHITE
% Set the colormap
colormap(cm);
% Write the text according to the color
[r,c]=find(x(1:end-1,1:end-1) == 1);
for i=1:length(r)
if(fig_idx == 1)
ht=text(c(i)+.1,r(i)+.5,num2str(x(r(i),c(i))));
else
ht=text(c(i)+.1,r(i)+.5,'SUR');
end
set(ht,'fontweight','bold','fontsize',10);
end
% Write the text according to the color
[r,c]=find(x(1:end-1,1:end-1) == 2);
for i=1:length(r)
if(fig_idx == 1)
ht=text(c(i)+.1,r(i)+.5,num2str(x(r(i),c(i))));
else
ht=text(c(i)+.1,r(i)+.5,'DBL');
end
set(ht,'fontweight','bold','fontsize',10);
end
% Write the text according to the color
[r,c]=find(x(1:end-1,1:end-1) == 3);
for i=1:length(r)
if(fig_idx == 1)
ht=text(c(i)+.1,r(i)+.5,num2str(x(r(i),c(i))));
else
ht=text(c(i)+.1,r(i)+.5,'HIT');
end
set(ht,'fontweight','bold','fontsize',10);
end
% Write the text according to the color
[r,c]=find(x(1:end-1,1:end-1) == 4);
for i=1:length(r)
if(fig_idx == 1)
ht=text(c(i)+.1,r(i)+.5,num2str(x(r(i),c(i))));
else
ht=text(c(i)+.1,r(i)+.5,'STK');
end
set(ht,'fontweight','bold','fontsize',10);
end
% Create and set the X labels
xt=.5:10.5;
xtl={' ';'2';'3';'4';'5';'6';'7';'8';'9';'10';'A'};
set(gca,'xtick',xt);
set(gca,'xticklabel',xtl,'xaxislocation','top','fontweight','bold');
% Create and set the X labels
yt=.5:24.5;
ytl={' ';'Soft20';'Soft19';'Soft18';'Soft17';'Soft16';'Soft15';'Soft14';'Soft13'; ...
'20';'19';'18';'17';'16';'15';'14';'13';'12';'11';'10';'9';'8';'7';'6';'5'};
set(gca,'ytick',yt);
set(gca,'yticklabel',ytl,'fontweight','bold');
title('Dealer''s Card')
end
Table with the values in the input matrix
Table with the user-defined strings
This is an answer inspired by il_raffa's answer, but with also quite a few differences. There is no better or worse, it's just a matter of preferences.
Main differences are:
it uses imagesc instead of pcolor
it uses a second overlaid axes for fine control of the grid color/thickness/transparency etc...
The association between value - label - color is set right at the beginning in one single table. All the code will then respect this
table.
It goes like this:
%% Random data
n_row = 24;
n_col = 10;
vals = randi([1 4], n_row, n_col);
%% Define labels and associated colors
% this is your different labels and the color associated. There will be
% associated to the values 1,2,3, etc ... in the order they appear in this
% table:
Categories = {
'SUR' , [1 0 0] % red <= Label and color associated to value 1
'DBL' , [0 0 1] % blue <= Label and color associated to value 2
'HIT' , [0 1 0] % green <= Label and color associated to value 3
'STK' , [1 1 1] % white <= you know what this is by now ;-)
} ;
% a few more settings
BgColor = 'w' ; % Background color for various elements
strTitle = 'Dealer''s Card' ;
%% Parse settings
% get labels according to the "Categories" defined above
labels = Categories(:,1) ;
% build the colormap according to the "Categories" defined above
cmap = cell2mat( Categories(:,2) ) ;
%% Display
hfig = figure('Name',strTitle,'Color',BgColor,...
'Toolbar','none','Menubar','none','NumberTitle','off') ;
ax1 = axes ;
imagesc(vals) % Display each cell with an associated color
colormap(cmap); % Set the colormap
grid(ax1,'off') % Make sure there is no grid
% Build and place the texts objects
textStrings = labels(vals) ;
[xl,yl] = meshgrid(1:n_col,1:n_row);
hStrings = text( xl(:), yl(:), textStrings(:), 'HorizontalAlignment','center');
%% Modify text color if needed
% (White text for the darker box colors)
textColors = repmat(vals(:) <= 2 ,1,3);
set(hStrings,{'Color'},num2cell(textColors,2));
%% Set the axis labels
xlabels = [ cellstr(num2str((2:10).')) ; {'A'} ] ;
ylabels = [ cellstr(num2str((5:20).')) ; cellstr(reshape(sprintf('soft %2d',[13:20]),7,[]).') ] ;
set(ax1,'XTick', 1:numel(xlabels), ...
'XTickLabel', xlabels, ...
'YTick', 1:numel(ylabels), ...
'YTickLabel', ylabels, ...
'TickLength', [0 0], ...
'fontweight', 'bold' ,...
'xaxislocation','top') ;
title(strTitle)
%% Prettify
ax2 = axes ; % create new axe and retrieve handle
% superpose the new axe on top, at the same position
set(ax2,'Position', get(ax1,'Position') );
% make it transparent (no color)
set(ax2,'Color','none')
% set the X and Y grid ticks and properties
set(ax2,'XLim',ax1.XLim , 'XTick',[0 ax1.XTick+0.5],'XTickLabel','' ,...
'YLim',ax1.YLim , 'YTick',[0 ax1.YTick+0.5],'YTickLabel','' ,...
'GridColor',BgColor,'GridAlpha',1,'Linewidth',2,...
'XColor',BgColor,'YColor',BgColor) ;
% Make sure the overlaid axes follow the underlying one
resizeAxe2 = #(s,e) set(ax2,'Position', get(ax1,'Position') );
hfig.SizeChangedFcn = resizeAxe2 ;
It produces the following figure:
Of course, you can replace the colors with your favorite colors.
I would encourage you to play with the grid settings of the ax2 for different effects, and you can also play with the properties of the text objects (make them bold, other color etc ...). Have fun !
I use FFMPEG and Imagemagick to extract the color palette from an image or video with a Windows batch file,
:: get current folder name
for %%* in (.) do set CurrDirName=%%~nx*
:: get current filename
for /R %1 %%f in (.) do (
set CurrFileName=%%~nf
)
ffmpeg -i "%1" -vf palettegen "_%CurrFileName%_temp_palette.png"
convert "_%CurrFileName%_temp_palette.png" -filter point -resize 4200%% "_%CurrFileName%_palette.png"
del "_%CurrFileName%_temp_palette.png"
This outputs something like,
I need this to have better transition throughout the color blocks though, like all blues from darkest to lightest then transitioning to greens, yellows etc. like,
Is there a way/switch to create this with either Imagemagick/FFMPEG?
I don't like working on Windows, but I wanted to show you a technique you could use. I have therefore written it in bash but avoided nearly all Unix-y stuff and made it very simple. In order to run it on Windows, you would only need ImageMagick and awk and sort which you can get for Windows from here and here.
I'll demonstrate using an image of random data that the script creates on around the third line:
Here is the script. It is pretty well commented and should convert easily enough to Windows if you like what it does.
#!/bin/bash
# Create an initial image of random data 100x100
convert -size 100x100 xc:gray +noise random image.png
# Extract unique colours in image and convert to HSL colourspace and thence to text for "awk"
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | awk -F"[(), ]+" '
!/^#/{
H=$3; S=$4; L=$5 # Pick up HSL. For Hue, 32768=180deg, 65535=360deg. For S&L, 32768=50%, 65535=100%
NGROUPS=4 # Change this according to the number of groups of colours you want
bin=65535/NGROUPS # Calculate bin size
group=int(int(H/bin)*bin) # Split Hue into NGROUPS
printf "%d %d %d %d\n",group,H,S,L
}' > groupHSL.txt
# Sort by column 1 (group) then by column 4 (Lightness)
sort -n -k1,1 -k4,4 < groupHSL.txt > groupHSL-sorted.txt
# Reassemble the sorted pixels back into a simple image, 16-bit PNM format of HSL data
# Discard the group in column 1 ($1) that we used to sort the data
awk ' { H[++i]=$2; S[i]=$3; L[i]=$4 }
END {
printf "P3\n"
printf "%d %d\n",i,1
printf "65535\n"
for(j=1;j<=i;j++){
printf "%d %d %d\n",H[j],S[j],L[j]
}
}' groupHSL-sorted.txt > HSL.pnm
# Convert HSL.pnm to sRGB.png
convert HSL.pnm -set colorspace hsl -colorspace sRGB sRGB.png
# Make squareish shape
convert sRGB.png -crop 1x1 miff:- | montage -geometry +0+0 -tile 40x - result.png
If I set NGROUPS to 10, I get:
If I set NGROUPS to 4, I get:
Note that, rather than using pipes and shell tricks, the script generates intermediate files so you can easily see each stage of the processing in order to debug it.
For example, if you run this:
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | more
you will see the output that convert is passing to awk:
# ImageMagick pixel enumeration: 10000,1,255,hsl
0,0: (257,22359,1285) #015705 hsl(1.41176,34.1176%,1.96078%)
1,0: (0,0,1542) #000006 hsl(0,0%,2.35294%)
2,0: (41634,60652,1799) #A2EC07 hsl(228.706,92.549%,2.7451%)
3,0: (40349,61166,1799) #9DEE07 hsl(221.647,93.3333%,2.7451%)
4,0: (31868,49858,2056) #7CC208 hsl(175.059,76.0784%,3.13725%)
5,0: (5140,41377,3341) #14A10D hsl(28.2353,63.1373%,5.09804%)
6,0: (61423,59367,3598) #EFE70E hsl(337.412,90.5882%,5.4902%)
If you look at groupHSL-sorted.txt, you will see how the pixels have been sorted into groups and then increasing lightness:
0 0 53456 10537
0 0 18504 20303
0 0 41377 24158
0 0 21331 25700
0 0 62708 28270
0 0 53199 31354
0 0 23130 32896
0 0 8738 33410
0 0 44204 36494
0 0 44204 36751
0 0 46260 38293
0 0 56283 40606
0 0 53456 45489
0 0 0 46517
0 0 32896 46517
0 0 16191 50372
0 0 49601 55769
0 257 49601 11565
0 257 42148 14392
0 257 53713 14649
0 257 50115 15677
0 257 48830 16191
Windows is particularly awkward at quoting things - especially scripts in single quotes like I use above for awk. I would suggest you extract the two separate awk scripts into separate files something like this:
script1.awk
!/^#/{
H=$3; S=$4; L=$5 # Pick up HSL. For Hue, 32768=180deg, 65535=360deg. For S&L, 32768=50%, 65535=100%
NGROUPS=4 # Change this according to the number of groups of colours you want
bin=65535/NGROUPS # Calculate bin size
group=int(int(H/bin)*bin) # Split Hue into NGROUPS
printf "%d %d %d %d\n",group,H,S,L
}
and
script2.awk
{ H[++i]=$2; S[i]=$3; L[i]=$4 }
END {
printf "P3\n"
printf "%d %d\n",i,1
printf "65535\n"
for(j=1;j<=i;j++){
printf "%d %d %d\n",H[j],S[j],L[j]
}
}
Then the two lines in the main script will become something like:
convert image.png -unique-colors -colorspace hsl -depth 8 txt: | awk -F"[(), ]+" -f script1.awk > groupHSL.txt
and
awk -f script2.awk groupHSL-sorted.txt > HSL.pnm
I tried this code to mix colors and may someone please describe the code to me?
#echo off
setlocal EnableDelayedExpansion
set hexa=0123456789ABCDEF
set /P "first=Enter first color (hexa digit): "
set /P "second=Enter second color (hexa digit): "
set /A sum= (0x%first% + 0x%second%) %% 16
set result=!hexa:~%sum%,1!
color %result%
echo The result is: %result%
I know this is part of my 1st question, but I just need help on how to use it correctly.
I'm sorry for asking this stupid question in the first place... I was doing a ton of research and some of them didnt work out properly and i was hoping for easier ways to get what I wanted. Sorry guys =(
In the original question the user ask for "mix 2 batch colors into another color (for example: Red + Yellow to make Orange)". I answered with the color table of color command, that uses 16 different colors with values from 0 to F in hexadecimal (equivalent to 0 to 15 in decimal):
0 = Black 8 = Gray
1 = Blue 9 = Light blue
2 = Green A = Light green
3 = Aqua B = Light aqua
4 = Red C = Light red
5 = Magenta D = Light magenta
6 = Brown E = Yellow
7 = White F = Bright white
I elaborated on his example: Red value is 4 + Yellow value is E (decimal 14) = 12 in hexadecimal (18 decimal). This result is outside of the valid color range so an adjustment is needed, and the usual way to do this adjust is taking the remainder of the large number when it is divided by the base value, 16 in this case. This is what this line do:
set /A sum= (0x%first% + 0x%second%) %% 16
You may enter set /? for further description of previous line. This way, the remainder when 18 decimal is divided by 16 decimal is 2, that correspond to Green color. In hexadecimal notation is easier to get the remainder because it is just the last digit. Another way to get this remainder is starting at the first value in previous table and jump the number of colors of second value, returning to first color (0) when the table ends.
You may try other "color mixing" cases, for example: Blue (1) + Brown (6) = White (7); Aqua (3) + Light blue (9) = Light red (C, decimal 12); Magenta (5) + Light magenta (D, decimal 13) = 12 (decimal 18) = Green (2).
Note that if you "add" Grey color (8) to any other color, the result is a switching between the dark and light versions of that color.
Ohk, heres a step by step of your code:
#echo off
Turns Echo off meaning any commands executed can't be seen by the user, instead only input and output can be seen
setlocal EnableDelayedExpansion
Allows the use of ! to Expand Variables if % has already been Expanded
set hexa=0123456789ABCDEF
Creates a variable hexa with value of all valid hexadecimal digits.
set /P "first=Enter first color (hexa digit): "
Takes one line of input prompting with the above text, and sets first to it.
set /P "second=Enter second color (hexa digit): "
Takes one line of input prompting with the above text, and sets seconds to it.
set /A sum= (0x%first% + 0x%second%) %% 16
creates a variable sum which is set to the solution to the above equation
set result=!hexa:~%sum%,1!
Creates a variable result which is set to hexa, from the sumth index and one letter ahead.
color %result%
sets the screen colour to the hexadecimal value of result
echo The result is: %result%
Outputs to the console the above text including the value of the variable result.
That explains it quite well, and if you want this code to do something else, feel free the ask.
Mona.
Color of CMD window can be customized like following (I take some sentences from 'color' command help):
Color attributes are specified by TWO hex digits -- the first
corresponds to the background; the second the foreground. Each digit
can be any of the following values:
0 = Black 8 = Gray
1 = Blue 9 = Light Blue
2 = Green A = Light Green
3 = Aqua B = Light Aqua
4 = Red C = Light Red
5 = Purple D = Light Purple
6 = Yellow E = Light Yellow
7 = White F = Bright White
So the color can be specified by following command:
color F9
where F is the background color and 9 is the text color.
The rest in the code you posted is taking values from input and call this command.
I have the following code:
fprintf(temp->_fstream, "plot '-' using 1:2 title 'tittle1'\n");
_fstream is a gnuplot pipe, using the '-' enables to write the data to gnuplot directly instead of writing it first to a file, this is the code that does that:
fprintf (_stream->_fstream, "%d ", _node->count);
now I would like to plot another two columns say 1:3, for example in gnuplot you would do this using:
plot "output3.txt" using 1:2 title 'prey', "output3.txt" using 1:3 title 'predator'
but doing the same thing via a pipe it gives an error saying unreachable data source here is the line that I am using:
fprintf(temp->_fstream, "plot '-' using 1:2 title 'tittle1', '-' using 1:3 ... \n");
I've been looking at this for some time any help would be appreciated.
try this:
plot '-' us 1:2, '' us 1:2
and enter (or write to the stream) the data followed by 'e'.
Then, enter the second set of data followed by 'e'.
1 1
2 2
3 3
e
1 2
2 3
3 4
e