Drawing 256 squares/rectangles in MATLAB - matlab

I am trying to draw 256 small sized squares using MATLAB rectangle function. If I am drawing abut 10 squares then the following works fine:
for i=1:2:40
rectangle('Position',[5,3+i,0.3,0.3],...
'Curvature',[0,0],...
'LineStyle','-', 'faceColor', 'black')
end
axis off;
daspect([1,1,1])
But when I change the last value of for loop to 512 (to draw 256 squares), it is not printing properly:
Here is the magnified version of a section of the above image:
This image clearly shows some thing is wrong somewhere as the sides of the squares are not perfectly equal and that the squares are becoming smaller in size for higher no. of squares: Can anybody help me draw the squares perfectly with size not diminishing, ? (I don't have any issues with memory, and I can tolerate multiple pages scrolling down for covering entire squares )

It is a classical Moire effect. You can't show that much rectangles on your monitor, because there aren't enough pixels. Matlab does some down-sampling for you. Thus, you get another frequency, that did not exist originally.

I tried your code and it works fine even when the loop does 512 iterations - when you zoom-in in the final matlab figure. The artifacts you describe are probably caused by the monitor resolution or a low resolution while exporting to non-vector files.
Try to export your image as a vector file (eps or svg) to see that everything looks fine when you zoom in.

Related

Limit of Decreasing Plot Size in MATLAB

I use MATLAB R2021b. I have a 10x10 data array and I am using contourf function to plot the data. By default, MATLAB gives me a figure with 1120x840 pixels.
I know that I can use the command set(gcf, 'position', [700, 700, 100, 100]) to decrease the size of the figure. And I get a figure with 200x200 pixels. I decided to shrink the value in the set function by half to get a 100x100 figure.
However, when I try to do set(gcf, 'position', [700, 700, 50, 50]) , I got a figure with size 100x160. No matter how much further I decrease the value in the set function, the second dimension of the figure remained at 160 pixels. And there's no problem with the first dimension -- it can shrink with the value in the set function.
Does anyone know what's the problem here? My goal is to get a figure with 100x100 pixels.
Thank you very much for any advice!
MATLAB has always had a minimal size for figure windows. A smaller window cannot contain the minimal set of menus and toolbar buttons.
But you don’t need a small window to export a small plot.
When exporting a plot, MATLAB uses the “PaperPosition” and “PaperUnits” figure properties. Set the units to pixels and the size to your required sizes to export the figure in those sizes.
There are of course other alternatives:
Set the axes to your required sizes, then export only the axes area (or crop the produced image to size).
Export a figure at twice (or four times) the size, then resample by a factor 1/2 (or 1/4).
If you’re not exporting, and just want a small display on the screen, consider putting multiple things in the same figure window, all you need to do is control the axes’s “Position” property.
I am the original poster. I think there is a minimum window size in both Windows and Mac operating systems. 100 pixels are smaller than the minimum windows size, so I cannot generate such a small figure.
This should be the answer for my question.

Export image at full resolution with axes in MATLAB

I am trying to save a large image (1641x6139) at full resolution with MATLAB with axes. Doing this without axes is easy using the imwrite command. To plot the image with axes, I write:
image(x,y,my_image);
Because the image is very large, MATLAB automatically reduces the resolution of the image. The window size would have to be significantly larger than the screen to display the entire image at full resolution. I have tried a couple different approaches to exporting the figure and each runs into the same problem: the image is pixelated at a coarser resolution than the original image. The problem is not that the new image has fewer pixels; instead, neighboring pixels have been assigned the same value, creating the appearance of coarser-scale pixelation.
For example, where H is the figure handle, I tried:
set(H, 'PaperPosition', [0, 0, width , height ])
print -dpng -r500 my_filename
Increasing width, height, or resolution all had the effect of increasing the number of pixels in the image, but the apparent pixelation is unchanged.
I also tried using the function export_fig, which seems to be designed for this type of problem, claiming to export figures with contained images in their native resolution. The resulting image appears to have the correct number of pixels, but as before the problem is that neighboring pixels have the same value, creating the appearance of coarser pixelation absent from the original image. The code I used is:
export_fig(my_filename,'-a1','-native')
Here are a couple images showing roughly the same zoomed in portion of my image:
The first is the original image and the second is the image resulting from export_fig. The second looks pixelated, although again note that each image contains roughly the same number of actual pixels.
Any advice/solutions would be much appreciated! This problem has been much more frustrating than I expected.
I figured out a simple solution. First, I create a blank image of the correct size, add the axes, and then use export_fig to generate an image of the axes. Then, I write my full-resolution image into the image matrix, and save the resulting image using imwrite.

Is there any way to "stretch" a given colormap for a larger range?

I'm building a MATLAB program to visualize a simulation of particles clustering.
Our simulation usually runs with around 10000 particles and the clusters might get to be around 5000 particles in size and I wanted to color the clusters by size so i inserted the following code:
a=[1 1 1 500]; %means x=1 y=1 z=1 and clustersize=500
colormap(flipud(pink));
scatter3(a(:,1),a(:,2),a(:,3),repmat(10,numel(a(:,1)),1),a(:,4),'filled','MarkerEdgeColor', 'k')
and after a cluster reaches a certain size it becomes "saturated" and sticks with the same color even when growing to be twice that size.
I've tried using colormap(hsv(1024)); to make a larger color map but that isn't very good for me either since i want to use a uniform gradient from light to dark and now necessarily mess around with lots of various colors, as the aren't distinguishable enough.
Any ideas how to stretch colormap(flipud(pink)); so it'll get saturated only around 5000? or alternatively let me know if there is some other solution that'll give me a higher "dynamic range"
Ok, so while trying to answer Luis Mendo I started making a gif of the simulation, and decided to add a colorbar; to the figure, then I saw that the colorbar stretched itself from figure to figure.
I found the code
lowrange = 1;
highrange = 5000;
caxis manual
caxis([lowrange highrange]);
which I used earlier for another simulation worked to predetermine the colorbar;'s range. this apparently meant the range of the colormap was also "stretched" or used the predetermined range.
Here are two clips from the simulation, one with the caxis fix, and one without, notice how the colorbar changes without the fix, that caused the particles to loop black(saturated) the for most of the simulation, regardless of the cluster size.
simulation without the corrected caxis code
simulation with corrected caxis code

Can't drag 'imrect' object for high resolution images

I'm making a GUI (with GUIDE) in which there is an axis used to display image sequences. In order to let the user select a region of interest in the sequence I'm using 'imrect'. The problem is the following: everything goes fine when images are smaller than 512x512 pixels (approximately), however for larger images (I tried 600x600 and 1024x1024) the rectangle does appear, I can change its size but I can't drag it around. I though it had to be with axis units so I changed the property from 'pixels' to 'normalized' and use normalized coordinates, but it does not work.
Here is my code to create the rectangle and restrain its movement to the axis limits:
hROI = imrect(hVideo,[Width/4 Height/4 Width/2 Height/2]; % Arbitrary size and position of the rectangle, centered on the image.
fcn = makeConstrainToRectFcn('imrect',get(gca,'XLim'),get(gca,'YLim'));
setPositionConstraintFcn(hROI,fcn);
When I perform the same operation on those large images outside the GUI it works. Any hint is welcome!
thanks
I found a workaround to the problem, in case it can help someone:
In the call to imshow just before calling imrect, we need to specify the axis limits as the "XData" and "YData" parameters.
Example:
imshow(Movie{Frame},'parent',handles.axes1_Video,'XData',get(gca,'XLim'),'YData',get(gca,'YLim'))
It works for images up to 1024x1024.

what does MajorAxisLength property in regionprop matlab function mean?

I am using regionprop function in matlab to get MajorAxisLength of an image. I think logically this number should not be greater than sqrt(a^2+b^2) in wich a abd b are the width and heigth of the image. but for my image it is. My black and white image contains a black circle in the center of the image. I think this is strange. Can anybody help me?
Thanks.
If you look at the code of regionprops (subfunction ComputeEllipseParams), you see that they use the second moment to estimate the ellipsoid radius. This works very well for ellipsoid-shaped features, but not very well for features with holes. The second moment increases if you remove pixels from around the centroid (which is, btw, why they make I-beams). Thus, the bigger the 'hole' in the middle of your image, the bigger the apparent ellipsoid radius.
In your case, you may be better off using the extrema property of regionprops, and to calculate the largest radius from there.