Mask overlay with matlab - image

I have the following code which shows an image called zero.
I would like just to overlay a mask image (only 0 and 1 values) of the same dimensions so that 0 values are transparent (and then we can see the values of the zero image) and 1 values are shown in black.
What could I do?
hFig = figure(1);
set(hFig, 'Position', [11 11 27 7.5]);
set( gca, 'Units', 'normalized', 'Position', [0.05 0.05 0.93 1.2] );
set(0,'defaultFigureUnits','centimeters');
m_proj('equidistant cylindrical','longitudes',[-15 21],'latitudes',[11.5 18]);
m_gridF('ytick',4,'tickdir','out','ticklen',0.005,'linestyle','none');
hold; Plat=18-[0:13]*0.5;
Plon=-15+[0:72]*0.5;
[Plg,Plt]=meshgrid(Plon,Plat);
m_pcolor(Plg,Plt,zero);shading flat;
hold on;
polarmap(flipud(polarmap),0)
M=m_shaperead('clip');
for k=1:length(M.ncst),
m_line(M.ncst{k}(:,1),M.ncst{k}(:,2),'color','k');
end
hold;
h=colorbar('SouthOutside');
set(h, 'Position', [0.13 .1 .78 .05]);
set(get(h,'title'),'string','test','fontsize',14)
hold;

Related

matlab plot data over an image

I would like to plot a scatter plot over a background image. But the origin of the image is at the top left corner. I need the bottom left of the image to be the origin so the bottom left = (0, 0.75) and top right (14, 1.25)
So I need to scale the image to my data from pH 0 - 14 (This is the x axis) and Eh 0.75 - 1.25 (This is the y axis)
Eh = [327.06 561.34 506.82 602.58 745.02 745.04 ...
693.96 682.9 648.46 468 412.18 522.94 459.74]./1e3; % V
pH = [6.4 4.51 5.08 4.98 3.63 4.31 6.24 6.22 4.94 6.44 7.05 5.09 4.63]; %pH
I=imread('Fe_Pourbaix.png');
xImg = linspace(0, 14, size(I, 2));
yImg = linspace(-0.75, 1.25, size(I, 1));
image(xImg, yImg, I, 'CDataMapping', 'scale');
hold on;
plot(pH, Eh,'*','LineWidth',2);
grid on;
Suppose I Need to flip the data? The below image is what I need is the x and y I need to produce to overlay my data

Colorbar resizes the subplots

I'm trying to plot 3 images side by side in MATLAB using subplot:
maxValue = 9;
minValue = 5;
figure(1)
subplot(1,3,1);
imshow(im1);
axis equal;
subplot(1,3,2);
imagesc(im2);colorbar;
caxis([minValue maxValue])
axis equal;
subplot(1,3,3);
imagesc(im3);colorbar;
caxis([minValue maxValue])
axis equal;
but the result looks like this:
Apparently the colorbar is resizing the image. How can I make all 3 images the same size and the colorbar fit the size of the image?
Your image is resized to maintain its aspect ratio according to the available space.
Use axis normal; for subplot(1,3,1) instead of axis equal.
You might need to maximise the figure window as well.
For im1 = imread('peppers.png');, the result is:
Here is what I ended up doing:
fig = figure(1);
set(fig, 'Position', [52 529 1869 445]); % Resize the image
subplot(1,3,1); % Add a subplot
subaxis(1,3,1, 'Spacing', 0.03, 'Padding', 0, 'Margin', 0); % Remove whitespace from subplot
imshow(im);
axis equal; % Use undistorted images
subplot(1,3,2);
subaxis(1,3,2, 'Spacing', 0.03, 'Padding', 0, 'Margin', 0);
imagesc(depth_gt);colorbar;
caxis([minValue maxValue])
axis equal;
subplot(1,3,3);
subaxis(1,3,3, 'Spacing', 0.03, 'Padding', 0, 'Margin', 0);
imagesc(depth_pred);colorbar;
caxis([minValue maxValue])
axis equal;
You can get this 'position' my manually resizing the image and then printing the output of fig in the Matlab command terminal

changing size and position of color bar

I want to change the size and position of my map colorbar. When I try to change the size and location of the colorbar, it is distorted in shape, I don't know why. Can anybody kindly help me. Please guide me why the set command distorts the clorbar? The location of the color bar should be 'southoutside'.The code is as under:
clear all,close all,clc
ax = worldmap('world');
load geoid
R = georasterref('RasterSize',[180 360],'Latlim',[-90 90],'Lonlim', [0 360]);
levels = [-70 -40 -20 -10 0 10 20 40 70];
geoshow(geoid, R, 'DisplayType', 'contour','LevelList',levels,'Fill','on','LineColor','black')
coast = load('coast.mat');
geoshow(coast.lat, coast.long, 'Color', 'white', 'LineWidth', 1.5)
cb = contourcbar('peer',ax,'Location','southoutside');
caxis([-110 90])
colormap(hsv)
set(get(cb,'XLabel'),'String','Geoid Undulation in Meters')
a=get(cb); %gets properties of colorbar
a.Position %gets the positon and size of the color bar
set(cb,'Position',[0.10 0.20 0.80 0.08])% To change size and position

Animating With Gloss in Haskell

Here's my code for a little pattern that looks something like this. (Not the most efficient code I know). Now, I want to make stars rotate using animate. but I'm not sure how to use display and animate together in one program. Any help would be appreciated. Thanks.
import Graphics.Gloss
main = display (InWindow "Gloss" (700,700) (0,0))
black (picture 100)
picture :: Float -> Picture
picture 0 = text "Value cannot be 0"
picture number = scale 6.5 6.5 (color rose $ drawpicture number)
orangered, orangered2, orangered3 :: Color
orangered = makeColor 1.0 0.251 0.0 0.7
orangered2 = makeColor 1.0 0.251 0.0 0.5
orangered3 = makeColor 1.0 0.251 0.0 0.3
intervalsmall = [0,11.25,22.5,33.75,45,56.25,67.5,78.75]
intervalbig = [0,22.5,45,67.5,90,112.5,135,157.5,180,202.5,225,247.5,270,292.5,315,337.5]
xlist = [2,4..50]
ylist = [0,2..48]
squares = pictures[rotate x (line [(-50,0),(0,50),(50,0),(0,-50),(-50,0)]) | x <- intervalsmall]
stars = pictures[rotate x ((pictures [line [(-8.5,0),(0,50),(8.5,0)],line[(0,50),(0,0)]])) | x <- intervalbig]
grid = pictures[line [(0,y),(x,50)] | x <- xlist, y <- ylist, x-y==2]
insidegrid = pictures[
translate 0 (-50) grid,
rotate 90 (translate 0 (-50) grid),
rotate 180 (translate 0 (-50) grid),
rotate 270 (translate 0 (-50) grid)]
drawpicture :: Float -> Picture
drawpicture number = pictures [
color red (pictures [circle 50,circle 8.5]),
line [(-50,-50),(-50,50),(50,50),(50,-50),(-50,-50)],
squares,
scale 0.7 0.7 squares,
scale 0.49 0.49 squares,
scale 0.347 0.347 squares,
scale 0.242 0.242 squares,
color orange stars,
color orange (scale 0.178 0.178 stars),
rotate 11.25 (scale 0.178 0.178 stars),
translate (-50) 0 grid,
rotate 90 (Translate (-50) 0 grid),
rotate 180 (Translate (-50) 0 grid),
rotate 270 (Translate (-50) 0 grid),
color orangered insidegrid,
color orangered2 (rotate 45 insidegrid),
color orangered3 (rotate 22.5 insidegrid),
color orangered3 (rotate 67.5 insidegrid)
]
It's easier if you have separate draw functions for each visual element, but the basic answer is: to animate it just use the animate function and rotate the image components you desire to "move":
import Graphics.Gloss
main = animate (InWindow "Gloss" (700,700) (0,0))
black picture
picture :: Float -> Picture
picture 0 = text "Value cannot be 0"
picture number = scale 6.5 6.5 (color rose $ drawpicture number)
orangered, orangered2, orangered3 :: Color
orangered = makeColor 1.0 0.251 0.0 0.7
orangered2 = makeColor 1.0 0.251 0.0 0.5
orangered3 = makeColor 1.0 0.251 0.0 0.3
intervalsmall = [0,11.25,22.5,33.75,45,56.25,67.5,78.75]
intervalbig = [0,22.5,45,67.5,90,112.5,135,157.5,180,202.5,225,247.5,270,292.5,315,337.5]
xlist = [2,4..50]
ylist = [0,2..48]
squares = pictures[rotate x (line [(-50,0),(0,50),(50,0),(0,-50),(-50,0)]) | x <- intervalsmall]
stars = pictures[rotate x ((pictures [line [(-8.5,0),(0,50),(8.5,0)],line[(0,50),(0,0)]])) | x <- intervalbig]
grid = pictures[line [(0,y),(x,50)] | x <- xlist, y <- ylist, x-y==2]
insidegrid = pictures[
translate 0 (-50) grid,
rotate 90 (translate 0 (-50) grid),
rotate 180 (translate 0 (-50) grid),
rotate 270 (translate 0 (-50) grid)]
rotVal :: Float -> Float
rotVal x = x - (x / (2*pi))
drawpicture :: Float -> Picture
drawpicture number = pictures [
rot $ color red (pictures [circle 50,circle 8.5]),
line [(-50,-50),(-50,50),(50,50),(50,-50),(-50,-50)],
rot $ squares,
rot $ scale 0.7 0.7 squares,
rot $ scale 0.49 0.49 squares,
rot $ scale 0.347 0.347 squares,
rot $ scale 0.242 0.242 squares,
rot $ color orange stars,
rot (color orange (scale 0.178 0.178 stars)),
rot (rotate 11.25 (scale 0.178 0.178 stars)),
translate (-50) 0 grid,
rotate 90 (Translate (-50) 0 grid),
rotate 180 (Translate (-50) 0 grid),
rotate 270 (Translate (-50) 0 grid),
rot $ color orangered insidegrid,
rot $ color orangered2 (rotate 45 insidegrid),
rot $ color orangered3 (rotate 22.5 insidegrid),
rot $ color orangered3 (rotate 67.5 insidegrid)
]
where rot = rotate (rotVal number)
It is too much to write out all for you but you just have to add another argument to your picture function that is a Float and represents time. So display would be replaced by animate. So.
main = animate (InWindow "Gloss" (700,700) (0,0))
black (picture 100)
picture :: Float -> Float -> Picture
picture number time = -- whatever you have to do
You'll have to change your helping drawing functions to take this time param. Let's say you want to rotate the whole think once ever 5 seconds you can just multiply this time coming in and get an angle angle = time*(pi*2/5) then you can use this angle for trig functions to calculate new x and y positions from the center.

Matlab: Something like "relative" position with uicontrol/axis; keep fixed margins when resizing

I currently have a big headache to get a small GUI working nicely which isn't being created with GUI editor but programmatically! What I have so far is something like the following:
hFig = figure();
set(hFig, 'Position', [300 200 500 400]);
plot((1:10).^2, '*-r');
% Größe des Plots so anpassen, dass links Platz für Buttons
ap = get(gca, 'TightInset');
fp = get(gcf, 'Position');
set(gca, 'Position', [160/fp(3), 30/fp(4), (fp(3)-180)/fp(3), (fp(4)-60)/fp(4)]);
uicontrol('Style', 'pushbutton', 'String', 'foo', 'Position', [15 fp(4)-60 110 30]);
uicontrol('Style', 'pushbutton', 'String', 'bar', 'Position', [15 fp(4)-100 110 30]);
Try to resize it: It doesn't 'look' the same, which means that the uicontrol boxes don't stay at the same relative position and the margins from the axis to the figure window get bigger. What I want to achieve is:
Have a figure window with a given position (x/y, width and height) with a plot inside. The plot will have a title and labels for x and y. Make the plot as height and width to have the TightInset plus a margin in each direction of a certain px-size (e.g. TightInset + 10px) as big as the figure window; except leave 150px of free space on the left to place some uicontrol buttons, and have them stay in the same position: This would be the same as being able to give the position from top/left (top = 20, left = 10) instead of bottom/left.
Thanks a lot!
Okay finally found a working solution I wanted it to be :-) Hopefully it is helpfull for somebody interested in it:
Main script file:
p = [300 300 1000 600];
fixedMargins = [250 0 0 0]; % [left, top, right, bottom]
f = figure('Position', p, 'Color', [0.9 0.9 0.9]);
plot(-10:10, (-10:10).^3, '*-r');
set(f, 'ResizeFcn', {#resizeCallback, gca, fixedMargins, {#myuiFunc, f, 40, 50}});
title('bla')
xlabel('foooooooooo')
ylabel('barrrrrrr')
Resize Callback Function:
% Need to pass the handle of the axis to modify (hAx) AND to pass the
% desired margins as second extra callback argument:
% [left, top, right, bottom]!
function resizeCallback(hFig, ~, hAx, fixedMargins, func)
% Disable automatic rezising
set(hAx, 'Units', 'pixels');
% Figure-Size
fp = get(hFig, 'Position');
% Calculate Position of the axis
margin = get(hAx, 'TightInset') * [-1 0 1 0; 0 -1 0 1; 0 0 1 0; 0 0 0 1];
% Position to fill the figure minus the TightInset-Margin
newPos = [0 0 fp(3:4)] - margin;
% Change position based on margins
newPos(1) = newPos(1) + fixedMargins(1);
newPos(3) = newPos(3) - fixedMargins(1) - fixedMargins(3);
newPos(2) = newPos(2) + fixedMargins(4);
newPos(4) = newPos(4) - fixedMargins(2) - fixedMargins(4);
% Set new position
set(hAx, 'Position', newPos);
% Call UI-Func
if(nargin == 5)
f = func{1};
args = func(2:end);
f(args{:});
end
end
You can pass whatever function you want to be called when resizing the figure window, e.g. to update something in the figure. In my example it's the myuiFunc(), which is the following:
function myuiFunc(hFig, left, top)
persistent handles;
if(~isempty(handles))
delete(handles);
handles = [];
end
fp = get(hFig, 'Position');
h1 = uicontrol('Style', 'pushbutton', 'String', 'Foo','Position', [left fp(4)-top 100 35]);
h2 = uicontrol('Style', 'pushbutton', 'String', 'Bar','Position', [left fp(4)-top-50 100 35]);
handles = [h1 h2];
end
I like it :) Hopefully you too!
Edit: No need to edit the resizeCallback Function! Should work if you just pass your desired margins to it and if you like, additionally a function handle with arguments which will be called for each resize!
You can also use "Normalized" units.
uicontrol('Style', 'pushbutton', 'String', 'foo', 'Units','normalized','Position', [0.90 0.05 0.08 0.08] );

Resources