Related
I have a gui which list two types of things in the menubar. The solution that was found was to limit the number of elements in the context menu to 25 :
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% construction menu éléments
function base=CreeMenuElem(noms,base,pref)
global kg4_HndlFig
hm=findobj(kg4_HndlFig,'Tag','Elem0');
delete(get(hm,'children')) %reset du menu éléments
set(hm,'Enable','on') %activation du menu éléments
if pref.CacheElem
noms=noms(~strncmp(noms,'#',1)); %suppression des éléments cachés
end
n=length(noms);
if pref.LimitMenu,MaxMenus=25;else MaxMenus=30;end
ChOld='';k=base;nm=0;
while (k<=n)
Ch=noms{k};
p=strfind(Ch,'::');
if isempty(p)
nm=nm+1; if nm>MaxMenus, break, end
uimenu(hm,...
'Label',Ch,...
'Tag','Element',...
'Callback','kgexec4');
ChOld='';
else
ChNew=Ch(1:p-1);
if ~strcmp(ChOld,ChNew)
nm=nm+1; if nm>MaxMenus, break, end
hb=uimenu(hm,'Label',ChNew);
ChOld=ChNew;
end
uimenu(hb,...
'Label',Ch,...
'Tag','Element',...
'Callback','kgexec4');
end
k=k+1;
end
if (base>1)|(k<n)
uimenu(hm,...
'Label',sprintf('(éléments %g à %g / %g) Suite...',base,k-1,n),...
'Separator','on',...
'Tag','SuiteElements',...
'Callback','kgexec4');
end
if k>n
base=1; %retour au début de la liste
else
base=k;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% construction menu barres
function base=CreeMenuBarr(noms,base,pref)
global kg4_HndlFig
hm=findobj(kg4_HndlFig,'Tag','Barre0');
delete(get(hm,'children')) %reset du menu barres
set(hm,'Enable','on') %activation du menu barres
noms=noms(2:end); %suppression de GND
if pref.CacheBarr
noms=noms(~strncmp(noms,'#',1)); %suppression des noms auto
end
n=length(noms);
if pref.LimitMenu,MaxMenus=25;else,MaxMenus=30;end
bb=min(base+MaxMenus-1,n); %dernier menu à afficher
for k=base:bb
uimenu(hm,...
'Label',noms{k},...
'Tag','Barre',...
'Callback','kgexec4' );
end
if (n>MaxMenus) && pref.LimitMenu
uimenu(hm,'Label',sprintf('(barres %g à %g / %g) Suite...',base,bb,n),...
'Tag','SuiteBarres', 'Separator','on', 'Callback','kgexec4' );
end
if bb<n, base=bb+1; else base=1; end %retour au début de la liste
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
I would like to be able to scroll in these menus instead of using this solution that can be impractical and slow but i don't understand how to add the scroll option. I tried with uicontrol but it never works.
Try
g=figure;
u=uipanel(g,'backgroundcolor',[1 0 1],'units','pixels','position',[1000 1000 g.InnerPosition(3)-19 1000]);
uu=findjobj(u);
j=javax.swing.JScrollPane(uu);
j.setHorizontalScrollBarPolicy(j.HORIZONTAL_SCROLLBAR_NEVER);
[jj hh]=javacomponent(j,[10 10 g.InnerPosition(3)-20 g.InnerPosition(4)-20],g);
%components to add to panel
button=uicontrol(u,'style','pushbutton','units','pixels',...
'position',[0.1 0.1 100 100],'string','blah');
or if that doesnt work this longer method from the MATLAB math works page
Example : I wish to create a panel with a variable number of lines and text edit boxes that the user can scroll through to edit. The main window handle is ptrMainGUI. I have two subpanels: one for the slider, and one for the content that it will scroll through: ptrPanelStimParamsParent and ptrPanelStimParams. intParams here is the number of lines I'm going to generate. As long as you create variables ptrMainGUI, as well as intParams, cellProps, cellVals, cellComments for your lines and values to generate in the panel I think it should work.
%get main GUI size and define subpanel size
ptrMainGUI.Units = 'pixels';
vecGuiSize = ptrMainGUI.Position;
ptrMainGUI.Units = 'normalized';
dblPanelHeight = 0.2;
dblPanelY = 0.1;
%calculate the total size of the subpanel content
dblTotSize = (intParams+1)*30;
dblRelSize = (dblTotSize/(vecGuiSize(end)*dblPanelHeight))+dblPanelHeight;
%create the panels
ptrPanelStimParamsParent = uipanel('Parent',sFigRE.ptrMainGUI);
set(ptrPanelStimParamsParent,'Position',[0.01 dblPanelY 0.94 dblPanelHeight]);
ptrPanelStimParams = uipanel('Parent',ptrPanelStimParamsParent);
set(ptrPanelStimParams,'Position',[0 0 1 dblRelSize]);
ptrSlider = uicontrol('Style','Slider','Parent',sFigRE.ptrMainGUI,...
'Units','normalized','Position',[0.94 dblPanelY 0.05 dblPanelHeight],...
'Value',1,'Callback',{#slider_callback1,ptrPanelStimParams});
%add all variables
vecParamTextPtrs = nan(1,intParams);
vecParamEditPtrs = nan(1,intParams);
for intParam=1:intParams
vecParamTextPtrs(intParam) = uicontrol(ptrPanelStimParams,'style','text',...
'Position',[1 (intParams*30)-((intParam-1)*30) 150 25],'String',cellProps{intParam},'FontSize',10);
vecParamEditPtrs(intParam) = uicontrol(ptrPanelStimParams,'style','edit',...
'Position',[150 (intParams*30)-((intParam-1)*30) 390 25],'String',cellVals{intParam},'Tooltip',cellComments{intParam},'FontSize',10);
end
%add callback
slider_callback1(ptrSlider,[],ptrPanelStimParams);
Now, to scroll properly we'll need to use the following function with some arcane transformations. The vecSize(end)-1 is to avoid showing an empty block the size of exactly one parent panel:
function slider_callback1(hObject,eventdata,ptrSubPanel)
vecSize = ptrSubPanel.Position;
val = get(hObject,'Value');
dblRealMax = vecSize(end) - 1;
dblStartY = val*dblRealMax;
vecSetPanelPos = [0 -dblStartY 1 vecSize(end)];
set(ptrSubPanel,'Position',vecSetPanelPos);%[from-left from-bottom width height]
end
I have the following code:
close all;
star = imread('/Users/name/Desktop/folder/pics/OnTheBeach.png');
blrtype = fspecial('average',[3 3]);
blurred = imfilter(star, blrtype);
[rows,cols,planes] = size(star);
R = star(:,:,1); G = star(:,:,2); B = star(:,:,3);
starS = zeros(rows,cols);
ind = find(R > 190 & R < 240 & G > 100 & G < 170 & B > 20 & B < 160);
starS(ind) = 1;
K = imfill(starS,'holes');
stats = regionprops(logical(K), 'Area', 'Solidity');
ind = ([stats.Area] > 250 & [stats.Solidity] > 0.1);
L = bwlabel(K);
result = ismember(L,find(ind));
Up to this point I load an image, blur to filter out some noise, do colour segmentation to find the specific objects which fall in that range, then create a binary image that has value 1 for the object's colour, and 0 for all other stuff. Finally I do region filtering to remove any clutter that was left in the image so I'm only left with the objects I'm looking for.
Now I want to recolour the original image based on the segmentation mask to change the colour of the starfish. I want to create Red,Green,Blue channels, assign value to them then lay the mask over the image. (To have red starfishes for example)
red = star;
red(starS) = starS(:,:,255);
green = star;
green(starS) = starS(:,:,0);
blue = star;
blue(starS) = star(:,:,0);
out = cat(3, red, green, blue);
imshow(out);
This gives me an error: Index exceeds matrix dimensions.
Error in Project4 (line 28)
red(starS) = starS(:,:,255);
What is wrong with my current approach?
Your code is kinda confusing... I don't understand whether the mask you want to use is starS or result since both look like 2d indexers. In your second code snippet you used starS, but the mask you posted in your question is result.
Anyway, no matter what your desired mask is, all you have to do is to use the imoverlay function. Here is a small example based on your code:
out = imoverlay(star,result,[1 0 0]);
imshow(out);
and here is the output:
If the opaque mask of imoverlay suggested by Tommaso is not what you're after, you can modify the RGB values of the input to cast a hue over the selected pixels without saturating them. It is only slightly more involved.
I = find(result);
gives you an index of the pixels in the 2D image. However, star is 3D. Those indices will point at the same pixels, but only at the first 2D slice. That is, if I points at pixel (x,y), it is equivalently pointing to pixel (x,y,1). That is the red component of the pixel. To index (x,y,2) and (x,y,2), the green and blue components, you need to increment I by numel(result) and 2*numel(result). That is, star(I) accesses the red component of the selected pixels, star(I+numel(result)) accesses the green component, and star(I+2*numel(result)) accesses the blue component.
Now that we can access these values, how do we modify their color?
This is what imoverlay does:
I = find(result);
out = star;
out(I) = 255; % red channel
I = I + numel(result);
out(I) = 0; % green channel
I = I + numel(result);
out(I) = 0; % blue channel
Instead, you can increase the brightness of the red proportionally, and decrease the green and blue. This will change the hue, increase saturation, and preserve the changes in intensity within the stars. I suggest the gamma function, because it will not cause strong saturation artefacts:
I = find(result);
out = double(star)/255;
out(I) = out(I).^0.5; % red channel
I = I + numel(result);
out(I) = out(I).^1.5; % green channel
I = I + numel(result);
out(I) = out(I).^1.5; % blue channel
imshow(out)
By increasing the 1.5 and decreasing the 0.5 you can make the effect stronger.
I build an alpha shape from some points (example given in code) and want to export the shape to a raster graphics format. I need the shape only, not the plot markings (axis, scales ect).
I need only the resulting triangle on white ground as a bitmap.
Scale needs to be 1 unit = 1 pixel.
x = [0 10 20 30 30 30 15];
y = [0 0 0 0 15 30 15];
shape = alphaShape (x',y');
plot (shape, 'FaceColor', 'black');
I have not found anything on how to export shapes or how to rasterize them. Is there any way to do that?
Run the following code after yours.
imgwidth = max(1, ceil(max(x) - min(x)));
imgheight = max(1, ceil(max(y) - min(y)));
ax = gca;
ax.Visible = 'off';
ax.XTickMode = 'manual';
ax.YTickMode = 'manual';
ax.ZTickMode = 'manual';
ax.XLimMode = 'manual';
ax.YLimMode = 'manual';
ax.ZLimMode = 'manual';
ax.Position = ax.OuterPosition;
af = gcf;
figpos = getpixelposition(af);
resolution=get(0, 'ScreenPixelsPerInch');
set(af, 'paperunits','inches', ....
'papersize',[imgwidth imgheight]/resolution, ....
'paperposition',[0 0 [imgwidth imgheight]/resolution]);
print(af,'out.png','-dpng',['-r',num2str(resolution)],'-opengl')
Things done:
Fetch data range and convert to image dimensions.
Turn off axes and ticks.
Minimize/remove padding space surrounding the actual content.
Map 1 unit in data into 1 pixel in output image.
Things not done:
Guarantee aspect ratio. (should work, though)
This screenshot shows non-unity aspect ratio output:
References
Mathworks - Save Figure at Specific Size and Resolution
MATLAB Central - saving a figure at a set resolution
Mathworks - print
Mathworks - Save Figure with Minimal White Space
I need to make some pie charts using Gnuplot. I used the code I found here, on SO. My data file looks like this:
Województwo Suma
Dolnośląskie 3.6
Kujawsko-Pomorskie 7.5
Lubelskie 4.7
Lubuskie 3.3
Łódzkie 8.1
Małopolskie 6.9
Mazowieckie 12.5
Opolskie 2.6
Podkarpackie 6
Podlaskie 3.4
Pomorskie 8
Śląskie 14
And my Gnuplot script:
#!/usr/bin/gnuplot
set encoding utf8
set datafile separator "\t"
set termoption enhanced
set terminal epscairo enhanced color dashed rounded size 8.5, 5.5
set output '2008-2015procent_pie.eps'
stats '2008-2015procent_pie.csv' u 2 noout # get STATS_sum (sum of column 2)
ang(x)=x*360.0/STATS_sum # get angle (grades)
perc(x)=x*100.0/STATS_sum # get percentage
set size square # square canvas
set xrange [-1:1.5]
set yrange [-1.25:1.25]
set style fill solid 1
unset border # remove axis
unset tics # remove tics on axis
unset colorbox # remove palette colorbox
unset key # remove titles
Ai = 0.0; Bi = 0.0; # init angle
mid = 0.0; # mid angle
i = 0; j = 0; # color
yi = 0.0; yi2 = 0.0; # label position
set palette defined (1 1 0.788 0.055, 2 0.090 0.161 0.659)
plot for [i=1:STATS_records] '2008-2015procent_pie.csv' u (0):(0):(1):(Ai):(Ai=Ai+ang($2)):(i) every ::i::i with circle linecolor palette,\
'2008-2015procent_pie.csv' u (mid=(Ai+ang($2)), Ai=2*mid-Ai, mid=mid*pi/360.0, -0.5*cos(mid)):(-0.5*sin(mid)):(sprintf('%.1f\%', $2, perc($2))) ever\
y ::1 w labels center font ',10',\
for [i=1:STATS_records] '2008-2015procent_pie.csv' u (1.45):(i*0.25):1 every ::i::i with labels left,\
for [i=1:STATS_records] '+' u (1.3):(i*0.25):(i) pt 5 ps 4 lc palette
I have 2 problems with this script:
I don't see all labels, is it possible to move the labels somehow that I could see them all?
Colours: here, on my pie chart I have basically only 2 colours - yellow and blue. How to make it so I could have a variety of colours, different colour for different value?
My chart looks like this now:
Thank you.
-----------------------------------------------------------------------------------------------------------------------------------EDIT
-----------------------------------------------------------------------------------------------------------------------------------
I changed a bit my script, as suggested by #RolandSmith, also, I modified a little my data file, Now it looks like this:
Województwo Suma
Dolnośląskie 3.6
Kujawsko-Pomorskie 7.5
Lubelskie 4.7
Lubuskie 3.3
Łódzkie 8.1
Małopolskie 6.9
Mazowieckie 12.5
Opolskie 2.6
Podkarpackie 6
Podlaskie 3.4
Pomorskie 8
Śląskie 14
Świętokrzyskie 2.8
Warmińsko-Mazurskie 4
Wielkopolskie 7.9
Zachodniopomorskie 4.6
And the modified script:
#!/usr/bin/gnuplot
set encoding utf8
set datafile separator "\t"
set termoption enhanced
set terminal epscairo enhanced color dashed rounded size 8.5, 5.5
set output '2008-2015procent_pie.eps'
stats '2008-2015procent_pie.csv' u 2 noout # get STATS_sum (sum of column 2)
ang(x)=x*360.0/STATS_sum # get angle (grades)
perc(x)=x*100.0/STATS_sum # get percentage
set size square # square canvas
set xrange [-1:1.5]
set yrange [-1.25:1.25]
set style fill solid 1
unset border # remove axis
unset tics # remove tics on axis
unset colorbox # remove palette colorbox
unset key # remove titles
Ai = 0.0; Bi = 0.0; # init angle
mid = 0.0; # mid angle
i = 0; j = 0; # color
yi = 0.0; yi2 = 0.0; # label position
set palette rgb 33,13,10;
plot for [i=1:STATS_records] '2008-2015procent_pie.csv' u (0):(0):(1):(Ai):(Ai=Ai+ang($2)):(i) every ::i::i with circle linecolor palette,\
'2008-2015procent_pie.csv' u (mid=(Ai+ang($2)), Ai=2*mid-Ai, mid=mid*pi/360.0, -0.5*cos(mid)):(-0.5*sin(mid)):(sprintf('%.1f\%', $2, perc($2))) every ::1 w labels center font ',10',\
for [i=1:STATS_records] '2008-2015procent_pie.csv' u (1.45):(i*0.25)-1.9:1 every ::i::i with labels left,\
for [i=1:STATS_records] '+' u (1.3):(i*0.25)-1.9:(i) pt 5 ps 4 lc palette
Now the problem is with labels - I still can't see all of them. There should be 16 labels, as you can see from the CSV file. I tried to change the page size, with no success. Thank you for help.
Current pie:
To move the labels in the pie-chart inwards or outwards, change the "-0.5" in front of the sin and cos. To move the labels and the color-squares, change (i*0.25) to (i*0.25)-1.2 in the third and fourth plot.
Update: Change (i*0.25) to e.g. (i*0.18) to make the distance between the labels smaller. And change ps 4 to e.g. ps 3 to make the squares smaller.
Define a larger palete. Your current one only has two entries. Get one with as least as much colors as you have entries. You could use colorbrewer to generate palette colors.
Some other points.
While this is really very clever, you're probably pushing gnuplot way beyond what it was intended. Consider using another tool like e.g. Python's matplotlib.
Your data doesn't add up to 100, but only to 80.6. So you should scale your figure properly using the ang and perc functions. I can't put my finger on it, but it doesn't look right.
In the sprintf, you should only use the percentage:sprintf('%.1f\%', perc($2))
I have (for me) a strange problem with the date on the x-axis.
I use the (imo) linux time in the first column like;
1385856000,1.69,0,10.33,0,1.69,10.33,-8.64,12.14,3.5
1385942400,0,0.94,3.33,8.51,0.94,11.84,-10.9,13.7,2.8
1386028800,0,0.51,4.96,8.65,0.51,13.61,-13.1,15.8,2.7
1386115200,0,0.01,3.42,6.49,0.01,9.91,-9.9,10.6,0.7
V
V
V
1388361600,0,0.63,4.21,7.65,0.63,11.86,-11.23,13.93,2.7
1388448000,0,0.18,4.47,8.29,0.18,12.76,-12.58,14.48,1.9
In this case december 2013 with 31 days. But the line begins with 30 (november?).
For now a draw a rectangle over de "30" but ofcourse thats not the way.
This is my script;
maand = "Dec"
jaar = "2013"
file = maand.jaar.'.txt'
set output maand.jaar.".png"
set datafile separator ","
set linestyle 1 lt 1 lc rgb "black"
set linestyle 2 lt 1 lc rgb "red"
set bmargin 2.2 # witruimte onder grafiek
set label font "arial, 7" # grootte font tbv labels in het grafiek
set boxwidth 0.8 relative
set terminal pngcairo truecolor enhanced size 1200, 500 background rgb "#FFF5F5"
stats file using 0 nooutput ; dagen = STATS_records
stats file using 10 nooutput ; zon = value(int(STATS_sum*1000))
stats file using 9 nooutput ; gebruikt = value(int(STATS_sum*1000))
afgenomen = gebruikt-zon
set timefmt "%s" ; fmt = "%s"
stats file using (strptime(fmt, stringcolumn(1))) every ::1::1 nooutput
maand = strftime("%B", STATS_max) ; jaar = strftime("%Y", STATS_max) ; datum = maand." ".jaar
set title 'Energie stromen '.datum font "arial bold, 14"
set xdata time ; set timefmt "%s" ; set format x "%d" # dit is de opmaak zoals je hem gaat zien
set xtics 86400 font "arial,12" offset -1.35,0.5
set mxtics 1
set grid ls 1 lc rgb "#dddddd"
set ytics font "arial, 12" offset 0.5,0
set ylabel "V e r m o g e n in kW" offset 3,1 font "helvetica, 12"
unset key
set key below left samplen 2
set key maxrows 1 # aantal regels onder het grafiek (met Watt/uur erin)
set style fill solid 1 border 0.5 # was transparent solid 0.5 border 0.5
set style rectangle fc linestyle 1 fs solid 0.5 noborder
set object rectangle front fillcolor rgb "#FFF5F5"
set object 2 rect from graph -.48, graph -1.5 to graph -0.004, graph 0.02 fc rgb "#FFF5F5"
plot file u ($1-43200):10 w boxes lc rgb "#00ff00" title "Deze maand zon: ".(zon/1000)." kW",\
file u ($1-43200):10:(sprintf("%2.1f",$10)) w labels offset 0.0,0.4 font "arial, 10" notitle,\
file u ($1-43200):(-1*$9) w boxes lc rgb "#ff0000" title "&{2}Verbruik: ".(gebruikt/1000)." kW",\
file u ($1-43200):(-1*$9):(sprintf("%2.1f",$9)) w labels offset 0,-0.4 font "arial, 10" notitle
Has some one a clou?
The 30 comes from november and the way you shift the xticlabels.
I think, the best way to have the labels below the boxes, but the tics and the grid lines between the boxes is the following:
Scale the major tics to 0
Add one minor xtic and draw the grid lines only for the minor xtics
Do not expand the automatic xrange to the next major tic (set autoscale xfix)
Plot the boxes at their actual time position (plot file u 1:... instead of plot file u ($1-43200):...)
...
set xtics 86400 font "arial,12" scale 0, 1
set mxtics 2
set grid mxtics ytics ls 1 lc rgb "#dddddd"
set autoscale xfix
...
plot file u 1:10 w boxes lc rgb "#00ff00"
...
With these modifications, your exemplary data and version 4.6.3 I get
BTW: You can compress your three stats calls to a single one:
stats file using 9:10 nooutput
dagen = STATS_records
zon = int(STATS_sum_y*1000)
gebruikt = int(STATS_sum_x*1000)