Transparent overlapping bar plots - matlab

I want to have two transparent bar plots that overlape in one figure. I tried this way:
bar(list2(:,1),list2(:,2),'r','FaceAlpha',0.5)
hold on
bar(list1(:,1),list1(:,2),'g','FaceAlpha',0.5)
but the output is:
Why the second plot is not transparent and has these strange strips?
I use matlab 2016a

your approach is correct, and it works for a few bars:
[list1(:,2),list1(:,1)] = hist(randn(200,1));
[list2(:,2),list2(:,1)] = hist([randn(100,1)-0.5 ; randn(100,1)+0.5]);
bar(list2(:,1),list2(:,2),'r','FaceAlpha',0.5)
hold on
bar(list1(:,1),list1(:,2),'g','FaceAlpha',0.5)
However, you can notice that there are black lines contouring each bar. As the bar number increases, the black contours will cover everything:
[list1(:,2),list1(:,1)] = hist(randn(3000,1), 300);
[list2(:,2),list2(:,1)] = hist([randn(1500,1)-2 ; randn(1500,1)+2], 300);
h1 = bar(list2(:,1),list2(:,2),'r','FaceAlpha',0.5)
hold on
h2 = bar(list1(:,1),list1(:,2),'g','FaceAlpha',0.5)
(The result will depend on the Matlab version. In 2016b it appears that the problem is automatically corrected).
The solution: remove the black contours:
h1.EdgeColor = 'none';
h2.EdgeColor = 'none';

Related

Outlines around segmented cells

The following lines, creates white rings (outlines) around my segmented cells
se1 = strel('diamond',10); se2 = strel('diamond',4);
R = imdilate([RED],se1)&[~imdilate([RED],se2)];
imshow(R)
And this line displays my segmented cells in RGB form.
r = imadjust(mat2gray(RED));
z = zeros(size(r),'like',r);
r = cat(3,r,z,z);
imshow(r)
Now, with a "hold on;" between two code, the outlines should be plotted around the red cells but it doesn't. I'm trying to plot white outlines around my segmented cells. Thanks for your help.

Find a nearly circular band of bright pixels in this image

This is the problem I have: I have an image as shown below. I want to detect the circular region which I have marked with a red line for display here (that particular bright ring).
Initially, this is what I do for now: (MATLAB)
binaryImage = imdilate(binaryImage,strel('disk',5));
binaryImage = imfill(binaryImage, 'holes'); % Fill holes.
binaryImage = bwareaopen(binaryImage, 20000); % Remove small blobs.
binaryImage = imerode(binaryImage,strel('disk',300));
out = binaryImage;
img_display = immultiply(binaryImage,rgb2gray(J1));
figure, imshow(img_display);
The output seems to be cut on one of the parts of the object (for a different image as input, not the one displayed above). I want an output in such a way that it is symmetric (its not always a perfect circle, when it is rotated).
I want to strictly avoid im2bw since as soon as I binarize, I lose a lot of information about the shape.
This is what I was thinking of:
I can detect the outer most circular (almost circular) contour of the image (shown in yellow). From this, I can find out the centroid and maybe find a circle which has a radius of 50% (to locate the region shown in red). But this won't be exactly symmetric since the object is slightly tilted. How can I tackle this issue?
I have attached another image where object is slightly tilted here
I'd try messing around with the 'log' filter. The region you want is essentially low values of the 2nd order derivative (i.e. where the slope is decreasing), and you can detect these regions by using a log filter and finding negative values. Here's a very basic outline of what you can do, and then tweak it to your needs.
img = im2double(rgb2gray(imread('wheel.png')));
img = imresize(img, 0.25, 'bicubic');
filt_img = imfilter(img, fspecial('log',31,5));
bin_img = filt_img < 0;
subplot(2,2,1);
imshow(filt_img,[]);
% Get regionprops
rp = regionprops(bin_img,'EulerNumber','Eccentricity','Area','PixelIdxList','PixelList');
rp = rp([rp.EulerNumber] == 0 & [rp.Eccentricity] < 0.5 & [rp.Area] > 2000);
bin_img(:) = false;
bin_img(vertcat(rp.PixelIdxList)) = true;
subplot(2,2,2);
imshow(bin_img,[]);
bin_img(:) = false;
bin_img(rp(1).PixelIdxList) = true;
bin_img = imfill(bin_img,'holes');
img_new = img;
img_new(~bin_img) = 0;
subplot(2,2,3);
imshow(img_new,[]);
bin_img(:) = false;
bin_img(rp(2).PixelIdxList) = true;
bin_img = imfill(bin_img,'holes');
img_new = img;
img_new(~bin_img) = 0;
subplot(2,2,4);
imshow(img_new,[]);
Output:

Matlab Transparent PNG (Upside Down/ Smaller Image)

I am trying to load a transparent image. It seems to work fine in the first part of the code but then fails. Here is the code
for l = 1:4
color = he;
color(something ~= l) = 0;
A = ((color(:,:,1)));
A( all(color == 0, 3 ) ) = 1;
file = strcat(file{k}, '.png');
segmented_images{k} = color;
transparency{k} = A;
chk = segmented_images{k};
f = imshow(chk);
set(f, 'AlphaData', transparency{k});
figure, imshow(chk), title("Working Fine");
end
Here the images appear to be transparent.
If I test it outside the loop:
my_alpha = transparency{1};
chk2 = segmented_images{1};
f = imagesc(chk2);
set(f, 'AlphaData', transparency{1});
figure, imshow(chk2),title('transparent Final');
imwrite(chk2, 'G:\path.png');
I see black color in transparent region. If I do this:
imwrite(chk2, 'G:\wamp\www\final_check.png', "Alpha", my_alpha);
I am able to save a transparent image. I am new to this color processing thing, so do excuse me if I am making a really silly mistake. Thank you
EDIT
Inside the loop image is printed twice, first time as transparent and second time with black background. It seems I am not displaying the image in correct way. Plus the title 'Working Fine' is attached to the black background image not to the other one.
EDIT2:
The real problem is that the image with alpha channel are being upside down.
What I get as a result is:
This is the code:
figure
hold on
h1 = image(segmented_images{1});
set(h1, 'AlphaData', transparency{1});
h2 = image(last_image);
set(h2, 'AlphaData', transparency{2});
h3 = image(segmented_images{3});
set(h3, 'AlphaData', transparency{3});
h4 = image(segmented_images{4});
set(h4, 'AlphaData', transparency{4});
hold off;
There are two issues here: one the image is smaller and upside down. Am I overlaying it correctly. Again I suspect it would be silly mistake that I can't find. Any help would be appreciated.
UPDATE:
When I change
h1 = image(segmented_images{1});
to
h1 = imshow(segmented_images{1});
I get the desired results. Can somebody explain how getting handler is different? I guess I need to go through documentation.
To change the y-direction use:
set ( axesHandle, 'YDir', 'reverse' )

Why sometimes the bars with bar or hist have no border?

I noticed that sometimes, when I plot the bars using the functions bar() or hist(), the bars plotted have no border. They are a little bit less nice to see, and I would prefer the border or a little bit of space between them.
The figure shows what I got now, plotting three different datasets. The third graph is zoomed in order to show the lack of space between bars.
I get there this has something to do with the 'histc' parameters in bar function. Without the histc parameters the bars have some space between each others, but then the bar will be centered on the edges values, whereas I want the edges values to be, well, EDGES of each bar.
This is (the relevant part of) the code I used:
[...]
if edges==0
%these following lines are used to take the min and max of the three dataset
maxx=max(cellfun(#max, reshape(data,1,size(data,1)*size(data,2))));
minn=min(cellfun(#min, reshape(data,1,size(data,1)*size(data,2))));
edges=minn:binW:maxx+binW;
end
[...]
y{k}=histc(data{r,c}, edges);
bar(edges,y{k} , 'histc');
[...]
I think if you change the color of your bar plots you'll see that there actually is a border it just doesn't show up very well. You can also change the width of the bars so that they are more distinct.
% something to plot
data = 100*rand(1000,1);
edges = 1:100;
hData = histc(data,edges);
figure
subplot(2,1,1)
h1 = bar(edges,hData,'histc');
% change colors
set(h1,'FaceColor','m')
set(h1,'EdgeColor','b')
% Change width
subplot(2,1,2)
h1 = bar(edges,hData,0.4,'histc');
The EdgeColor and LineWidth properties of the Barseries object control the bar outlines. Try using the code and playing with the red, green, blue, and width values to get a better result.
red = 1;
green = 1;
blue = 1;
width = 3;
h = bar(edges,y{k} , 'histc');
set(h,'EdgeColor',[red green blue],'LineWidth',width);

matlab: making an areaseries transparent disrupts subplots

I'm trying to make the red bands in the second subplot of the figure below go transparent with an opacity similar to alpha(0.2).
http://i.stack.imgur.com/zJjYk.jpg
However, when I try to call alpha(0.2) after the following code that generates the red bands:
Plotha1 = area([datenum(time(11,1),1,1) datenum(time(15,1),1,1)],[1.3*max(SA(:,2)) 1.3*max(SA(:,2))]);
set(Plotha1,'BaseValue',1.3*min(SA(:,2)),'FaceColor','r','LineStyle', 'none');
Plotha2 = area([datenum(time(4,1),1,1) datenum(time(8,1),1,1)],[1.3*max(SA(:,2)) 1.3*max(SA(:,2))]);
set(Plotha2,'BaseValue',1.3*min(SA(:,2)),'FaceColor','r','LineStyle', 'none');
alpha(0.2);
The third subplot goes blank like in the second figure.
http://i.stack.imgur.com/tjgIT.jpg
The code generating the third subplot comes last in my code:
subplot(3,1,3),
W = zeros(T,1);
PlotZeros = plot(datenum(time,1,1),W);
dateFormat = 'yyyy';
datetick('x',dateFormat);
hold on
PlotResid = plot(datenum(time,1,1),Resid);
set(PlotZeros,'Color',[0.5 0.5 0.5]); %grey
set(PlotResid,'Color','blue');
axis([datenum(time(1,1),1,1) datenum(time(end,1),1,1) 1.3*min(Resid) 1.3*max(Resid)])
hold off
I have tried moving things around so that the code generating the 2nd subplot comes last but it still causes the 3rd subplot to go blank. Does anyone know how to make these areaseries red bands go transparent without disrupting the 3rd subplot?
Thanks!
You could try using fill or patch with the 'facealpha' property instead of the area command:
% x and y vals define the 4 corners of the rectangle
% (slightly different than "area")
x_vals=[datenum(time(4,1),1,1) datenum(time(8,1),1,1) ...
datenum(time(8,1),1,1) datenum(time(4,1),1,1)];
y_vals=[1.3*min(SA(:,2)) 1.3*min(SA(:,2)) ...
1.3*max(SA(:,2)) 1.3*max(SA(:,2))];
Plotha2 = fill(x_vals,y_vals,'red','edgecolor','none','facealpha',0.2);