R plot expot with actual size - image

I'm new in R coding, so I need help or advise.
I'm building plot based on coordinates (originally this is eye tracking data). I`m exporting just dots without any axes or text. Later I will have to compare this dots with Image at which person was looking at.
So my aim is 1) to have exported image with very specific size (same to original image) and without any distortion (it seems to appear after manual entering of sizes in export dialog window). 2) to have this plot exported without extrafields, that obviously appers at every side.
Thank you in advance
UPD i`m thinking now if there is any way to move point of zero to left bottom corner of image? I was trying to work my problem out with cutting margins: par(mar=c(0, 0, 0, 0), xaxs='i', yaxs='i'), but it seems to cut all the empty parts of image. And I want to stay potentially working parts safe and keep size and proportions.
that is my source code
card1 <- "D:/01_experiment/02.04/p02/card1.txt"
table01 <- read.table(card1, strip.white = TRUE, sep="\t", header = TRUE)
jpeg('card81.jpg',
width = 842,
height = 595)
par(mar=c(0, 0, 0, 0), xaxs='i', yaxs='i')
plot(x = table01[,10],
y = table01[,11],
pch=20,
type="o",
#xaxt='n',
yaxt='n',
ann=FALSE,
bty="n",
xlab = "desity.x",
ylab = "desity.y"
)
dev.off()

Try this,
library(grid)
pdf("points.pdf", width=5, height=3)
grid.points(x <- runif(10), y <- runif(10), vp=dataViewport(x, y, extension = 0))
dev.off()

Related

How do I save just figure image without any graduation and numbers on x, y axis?

I used matlab code.
img = imread('cmap3.png')
map = jet(256)
ind = rgb2ind(img,map)
colormap(map)
cm = colormap('gray)
image(ind)
Through above code, I got the .
I want to save just the gray scale image without any graduations and numbers on x,y axis.
How do I remove them and save gray scale image?
If you use imwrite, you won't save the axes' labels.
For actual plots, there exists a different solutions, eg. described here: set the axis to start at the very left bottom corner so that there is no space left for descriptions: set(gca, 'Position',[0 0 1 1]). Than you can even use print to save the image/figure.

Matlab: binary image open to minimum rectangle size

I have a binary image:
and I'm trying to see if a 100x150 rectangle will fit in any blank space on the map.
I tried creating a rectangular strel & then eroding & dilating the picture to get rid of any areas smaller than needed:
se = strel('rectangle',[150, 100]);
BW = imerode(BW,se);
BW = imdilate(BW,se);
Unfortunately, it finds a hole prematurely
which is only 80x150. I think the erosion is failing since it's against the wall & only needs half the width, but don't know how to fix it.
Also, if I'm headed down the wrong path, please feel free to set me straight. Ultimately, I just need to find the upper-left corner of the a blank space at least as big as 100x150.
The approach below works quite well and runs fairly quickly. It has a few nested loops but you can probably further optimize the performance, I mainly just wanted to get it working for you. Keep in mind though that if you comment out the fprintf() and the plotting command, that will speed things up.
I downloaded your image from your Stack post but I believe that my downloaded version has a different size (398x398) than the raw data you are working with, so keep that in mind when viewing my results below.
As indicated in the code, you supply the width (w) and height (h), the algorithm then returns all of the (col, row) positions where the rectangle can fit.
Side Note: I believe this provides a solution to a 2D version of the Bin packing problem, but I'm not sure about that, you can check out the link above if thats of interest to you.
Either way, its a great example of computational problem where an exhaustive search can be a carried out rather quickly.
To verify the results, I added simple plotting of the rectangles. Keep in mind that if the rectangle fits in more than one position, a plot of the multiple rectangles begins to look rather jumbled as they are drawn repeatedly on top of one another (with offsets).
As an example case where only a single rectangle is found, I use: w = 29; h = 102; and then the result shows that the only position where this particular rectangle can fit, has the upper left corner = (row = 295, col = 368) (this rectangle size will likely only work for my downloaded version of your data):
In summary, I first I load the data and then convert to a binary map (0's and 1's):
% Note: '0' = black; '1' = white
data = round(im2double(rgb2gray(imread(filepath))));
figure(1);imshow(data); set(gcf,'Color',[1 1 1]);
hold on;
Input the search width and height:
w = 29;
h = 102;
sze = size(data);
numRows = sze(1);
numCols = sze(2);
Next we just do a search to see what will fit at each row and col position:
for col = 1:numCols - w - 1
for row = 1:numRows - h - 1
doesFit = fitshere(data, row,col, w, h);
if (doesFit == 1)
fprintf('row = %d; col = %d \n',row,col);
colX = [col col+w col+w col col];
colY = [row row row+h row+h row];
line(colX,colY,'Color','r','linewidth',2);
end
end
end
hold off;
You will need the following function to check if a given rectangle can fit in the array:
function [val] = fitshere(data, row, col, w, h)
val = 1;
for i = col:col + w
for j = row:row + h
if (data(j,i) == 0) % if this is true, we are in the black!
val = 0;
return;
end
end
end
return;
If your interested in knowing if your rectangle will fit at all (say either width X height or height X width), you can simply repeat the search after swapping the width and height.
Hope this helps.
lets do this with some matlab idioms
M=binaryImage;
sz=size(M);
nrows = 100;
ncols = 150 ;
colsum = cumsum(M,1);
cols_are_good = colsum(nrows+1:end,:)-colsum(1:end-nrows+1,:)==0;
% nrows empty rows below this point. in this column
rows_are_also_good = cols_are_good(:,ncols+1:end)-cols_are_good(:,1:end+1-ncols)==0;
and Bob's your uncle, that last variable contains 1 in all places that have nrows below them clear and each of those has ncols to the side

How to save figure with transparent background

I have a plot in Matlab and am setting the background to transparent by:
set(gcf, 'Color', 'None');
set(gca, 'Color', 'None');
When I try to save the image (from the viewer), I save as a ".png", but it saves with a white background. How can I save it with the transparent background?
It is disappointing but, MATLAB's default saveas and print commands cannot deal with transparent things very well. You'll have to save it with some background and then convert it either through imread/imwrite or some other tool.
There are some tools that might be helpful:
Export fig http://www.mathworks.com/matlabcentral/fileexchange/23629
svg export http://www.mathworks.com/matlabcentral/fileexchange/7401-scalable-vector-graphics-svg-export-of-figures
I prefer vector graphics, so use svg exports when transparency is needed. If indeed you have a bitmap, use imwrite(bitmapData, 'a.png', 'png', 'transparency', backgroundColor).
Things have changed since the MATLAB 2014b release. The newly implemented graphics system (so called HG2, for Handle Graphics version 2) does much better in terms of transparency.
Now it saves transparency correctly to SVG at least!
So I still wanted something simple that did not require me to install anything else (corporate pc not allowed :/). I stumbled upon this link, stating:
All you have to do is the following
1) In matlab file add the commands to format your figure with transparent background
set(gcf, 'color', 'none');
set(gca, 'color', 'none');
and save or export the figure generated in eps format. (say Bspline.eps)
2) Open Bspline.eps in NotePad
3) Look at the first line. For example %!PS-Adobe-3.0 EPSF-3.0. The last number 3.0 indicates the Postscript level. For level 3, search the string rf. You will find in one line like this (four numbers followed by rf)
0 0 3025 2593 rf %Comment that line using %.
(For level 2 search for string pr instead of rf)
Save the file.
Now you can use the eps file or you can convert it to pdf and then use it.
Anyway it will have transparent background
Extra
For me it was two lines with re and two lines, despite me having %!PS-Adobe-3.0 EPSF-3.0 just after each other. But the result was the Figure was now transparent.
As an addition to the answer by Memming. Matlab 2020 with exportgraphics supports transparent background but only for vectorized output (with doesn't work with rendered content). For exporting rendered data with transparency you can still not save it with transparency. However you can get the transparency by saving rendered data with two different background colors (white and black for example) and then loading both temporary images, solving a simple equation system and thereby retrieving the transparency and the original color data and then saving that all into a RGBA png file.
The key is to realize that the saved rendered output of Matlab is transparency times image data + (1 - transparency) times background color. From a single output, image data and transparency cannot be restored but from two outputs with different background colors it can. It would be easier if Matlab would support transparent background colors in rendered outputs, but this way works too.
Example script:
% create example data
g = -10:0.1:10;
[x, y, z] = ndgrid(g, g, g);
v = (x.^2 + y.^2 - 10).^2 + (z.^2 - 5).^2;
% render in 3D with transparency
fig = figure();
% one surface fully opaque
fv = isosurface(x, y, z, v, 20);
p = patch(fv, 'FaceColor', [1, 0, 0], 'FaceAlpha', 1, 'EdgeColor', 'none');
% another surface with transparency
fv = isosurface(x, y, z, v, 80);
p = patch(fv, 'FaceColor', [0, 1, 1], 'FaceAlpha', 0.5, 'EdgeColor', 'none');
fig.Children.Color = 'none'; % transparent background of figure axis
view([40 40]);
pbaspect([1,1,1]);
camlight;
lighting('gouraud');
% save figure in different ways
% save as vector format, doesn't produce nice output see for example https://stackoverflow.com/questions/61631063
exportgraphics(fig, 'test.pdf', 'ContentType', 'vector', 'BackGroundColor', 'none');
% prints warning: Warning: Vectorized content might take a long time to create,
% or it might contain unexpected results. Set 'ContentType' to 'image' for better performance.
% save as rendered output with transparent background not work
exportgraphics(fig, 'test.png', 'ContentType', 'image', 'BackGroundColor', 'none');
% prints warning: Warning: Background transparency is not supported; using white instead.
% now our solution, export with two background colors
exportgraphics(fig, 'test1.png', 'ContentType', 'image', 'BackgroundColor', 'k'); % black background
exportgraphics(fig, 'test2.png', 'ContentType', 'image', 'BackgroundColor', 'w'); % white background
% load exported images back in and scale to [0,1]
u = imread('test1.png');
u = double(u) / 255;
v = imread('test2.png');
v = double(v) / 255;
% recover transparency as a
a = 1 - v + u;
a = mean(a, 3);
a = max(0, min(1, a));
m = a > eps;
% recover rgb
c = zeros(size(u));
for i = 1 : 3
ui = u(:, :, i);
ci = c(:, :, i);
ci(m) = ui(m) ./ a(m);
c(:, :, i) = ci;
end
c = max(0, min(1, c));
% store again
imwrite(uint8(c*255), 'test.transparent.png', 'Alpha', a);
% temporary files test1.png and test2.png can now be deleted
These are the two temporary images with white and black background.
This is the resulting transparent image. To see that save the image and look at it with a suitable viewer.
One last comment: For high quality production figures you probably want to switch off (set the Visible property to off of) all rendered parts with transparency and save axes and labels as vectorized output, then reverse the visibility, i.e. switch off all axes and labels and only show the rendered parts with transparency and save them with two different background colors, then reconstruct the transparency and overlay both, the vectorized axes and labels as well as the rendered part with transparency and combine them. As of Matlab 2020b, Matlab is not capable of doing that on its own.
You can do it like this, Matlab2020a or a later version is valid!
x = 0:.1:2*pi;
y = sin(x);
figure;
plot(x,y,'LineWidth',4);
% save to transparented image
set(gcf, 'color', 'none');
set(gca, 'color', 'none');
exportgraphics(gcf,'transparent.emf',... % since R2020a
'ContentType','vector',...
'BackgroundColor','none')
According to Matlab staff exportgraphics(gca,'plot.png','BackgroundColor','none')
and similar should work in 2020a version, but when you try, you get beautifull errors in most cases:
Warning: Background transparency is not supported; using white instead.
I also got Warning: 'ContentType' parameter is ignored when it is set to 'vector' for image output. trying xing cui code.

Adding a color legend to an image

I have a matrix that I made an image of using image(matrix). Is there away to add a legend of the colors to my image like I do when adding a legend to plot?
Or the legend could be provided like this:
legend(grconvertX(0.5, "device"), grconvertY(1, "device"),
c("0",".5","1"), fill = colMap[c(1, 10, 20)], xpd = NA)
where grconvertX() and grconvertY() and xpd makes sure the legend is outside the plotting region.
A plausible example would be:
nsamples <- 20
mat <- rnorm(nsamples, .5, .15)
dim(mat) <- c(4, 5)
colMap <- colorRampPalette(c("red","white","blue" ))(nsamples)
image(1:4, 1:5, mat, col = colMap, ylab="", xlab="")
legend(grconvertX(0.5, "device"), grconvertY(1, "device"),
c("0",".5","1"), fill = colMap[c(1, 10, 20)], xpd = NA)
p.s.: I know it is an old request and it is solved. However I was looking for a similar answer and I could not find it. Since I bother solving this issue I thought maybe someone else could also benefit from it.
image in R is a fairly basic plotting function. You might want to look at filled.contour if you want a function that will automatically allocate space for a legend. Or try this:
library(lattice)
levelplot(matrix)
From the package fields, you could try image.plot. This function is based on the regular image, but it provides a figure legend.
library(fields)
x = 1:10
y = 1:15
z = outer( x,y,"+")
image.plot(x, y, z)

Love2d Rotating an image

I would like to rotate an image in Love2D.
I have found a documentation on love2d.org: https://love2d.org/wiki/love.graphics.rotate
But I can't seem to get it to work when I try to load an image.
Heres my code:
local angle = 0
function love.load()
g1 = love.graphics.newImage("1.png")
end
function love.draw()
width = 100
height = 100
love.graphics.translate(width/2, height/2)
love.graphics.rotate(angle)
love.graphics.translate(-width/2, -height/2)
love.graphics.draw(g1, width, height)
end
function love.update(dt)
love.timer.sleep(10)
angle = angle + dt * math.pi/2
angle = angle % (2*math.pi)
end
Could anyone show me an simple example of rotating an image in love2d?
https://love2d.org/wiki/love.graphics.draw
You may be better off using the fourth argument, shown as 'r' to rotate images, such as:
love.graphics.draw(image, x, y, math.pi/4)
It's not worth the trouble of using the translate functions for a single draw, and keeping those for when you're batching many draws at once.
Your code worked perfectly for me, aside from a small unrelated issue (love.timer.sleep uses seconds in LÖVE 0.8.0).
We will be able to help you better, and perhaps reproduce your error, if you provide us with more information.
When you say
I can't seem to get it to work when I try to load an image
..what is the result?
Is the image a white box? Does the application crash? Is there nothing on the screen?
All of these imply a image loading issue, rather than a rotation issue. Although, it could be the case that the image is rotating off of the screen.
If you continue to use translate, rotate, and scale (which is usually a good idea), I recommend you take a look at the push and pop functions.
They allow you to 'stack' transformations so you can render sub elements.
Example uses are rendering a GUI (each child pushes its translation and then renders the children) and drawing sprites on a scrolling map (the camera translates the entire map and then does for entity in entities do push() entity:draw() pop() end. Each entity can translate and rotate in local coordinates (0,0 = centre of sprite)).
love.graphics.draw( drawable, x, y, r, sx, sy, ox, oy, kx, ky )
the R is the rotation.. why don't you just set it to a variable and change it as you please? ... I'm new to programming so I may be wrong but this is how I would do it.
Example of rotating at center of image using LOVE 11.3 (Mysterious Mysteries):
function love.draw()
love.graphics.draw(img, 400,300, wheel.r, wheel.sx, wheel.sy, wheel.w / 2, wheel.h / 2)
end
function love.update(dt)
wheel.r = wheel.r + dt
end
function love.load()
wheel = {x = 0, y = 0, w = 0, h = 0, sx = 0.5, sy = 0.5, r = 0, image = "wheel.png"}
img = love.graphics.newImage(wheel.image)
wheel.w = img:getWidth()
wheel.h = img:getHeight()
end
Normaly the axis for rotating is the upper left corner. To center the axis to the middle of an image you have to use the parameters after the r parameter to half of width and half of height of the image.

Resources