How do I control the visual stacking order of images and colour bars in Matlab?
I have 6 images that I show on a 2 x 3 grid using subplot. I add colour bars to each of the images, but some of the colour bars appear behind the images, rendering them invisible. In my example, colour bars belonging to image 3 and 5 (counting as in the subplot command) appear behind their respective images.
I do not think I will be able to use the order of axes children objects, as each axes apparently only has one child, i.e. the image, and the colour bar object is child of the figure (Must be the same as its associated axes).
I have also tried uistack (with top for colour bars, and bottom for images), and although it does change appearances, in the end, other colour bars will wind up behind the images. It seems random which ones, for example after uistack on the image and colour bar belonging to subplot 5, the colour bar of subplot 2 will suddenly appear behind its image.
PS I also tried reordering the children of the figure, but they do not change (even with painters render)
It is very strange: When I just prepared the MCVE, the problem did not reproduce, but I have no idea what is different! Maybe a Windows update? Anyway, the original output with the problem is shown here http://i.stack.imgur.com/LJVG2.png, and the prepared example output which looks as it should here http://i.stack.imgur.com/F1LMX.png. So for now, there is no problem...
The code is
function example()
I1=ones(96,96);
I2=ones(96,96)+1;
I3=ones(96,96)+2;
I4=ones(96,96)+3;
I5=ones(96,96)+4;
I6=ones(96,96)+5;
pos=[10 10 12 9];
fig=figure
fig.Units='centimeters';
fig.Position=pos;
set(gcf,'PaperPositionMode','auto');
h(1)=veryTightSubPlot(2,3,1);
imshow(I1,[0,6]);
h(2)=veryTightSubPlot(2,3,2);
imshow(I2,[0,6]);
h(3)=veryTightSubPlot(2,3,3);
imshow(I3,[0,6]);
h(4)=veryTightSubPlot(2,3,4);
imshow(I4,[0,6]);
h(5)=veryTightSubPlot(2,3,5);
imshow(I5,[0,6]);
h(6)=veryTightSubPlot(2,3,6);
imshow(I6,[0,6]);
V=[0.315,0.65,0.97,0.315,0.65,0.97,0.315,0.65,0.97];
for i=1:6
p=get(h(i),'Position');
c=colorbar(h(i),'Axislocation','in','FontSize',8);
c.Color=[0,0,0];
cp=c.Position;
h(i).Position=p;
cp(3)=cp(3)/2;
c.Position=[V(i) cp(2:4)];
end
colormap(parula);
end
function [ax] = veryTightSubPlot(rows, columns,index)
ix = mod(index-1,columns);
iy = floor((index-1)/columns);
pos = [ix/columns,1-(iy+1)/rows,1/columns,1/rows];
ax = axes('ActivePositionProperty','outerposition','Position',pos);
end
Related
I want to animate a horizontal bar chart. The bars (squares) start at zero and grow within two easy-ease keyframes from 0 to a specific value. This value is displayed in a text layer. I have set up a slider which goes from zero to the specific value and controls both the text layer (value) and the size of the bar (width of square).
Problem: I want the value to follow the top of the bar chart as in here:
https://www.instagram.com/p/B7_5SOQFrW6/?utm_source=ig_web_copy_link
I tried to set easy-ease keyframes for the text layer too and adjust the values in the diagram editor. Result was too shaky and not nice to look at. Is there a solution with expressions?
source text of text layer for first Bar (1):
Math.round(thisComp.layer("controler").effect("1")("slider"))
source for square (first bar):
temp = thisComp.layer("controler").effect("1")("slider");
he_ = thisComp.layer("controler").effect("height")("slider");
[temp,wi_]
info: width is a slider with which I control the height of the bars.
Check this sample project, with both vertical and horizontal bars: https://url.io/ae_barchart
You can use sourceRectAtTime (like in the sample project), or calculate the position of the top side of your bar, knowing it's height and bottom Y coordinate and then translate it into Composition space from the bar layer`s space, so you can apply it to your Text Layer position.
If you check the position property of "bar_horizontal_text" / "bar_vertical_text" layers you'll see what I mean.
The rest of the setup is extra... just "fooling around". :-)
I have 2 images, with same dimension and same picture, a shape.
In the first image (that I show on screen), the shape is monocromatic, in the second image, shape is mapped with different color.
When I move the mouse, on the image, I want to show different text based on the color mapped on second (hidden) image.
I don't want to map square area, but irregular areas, this is my problem.
For example, when mouse cursor is on head (right image), I get color red on the left image (cached but not visualized) and I put a specific text.
How can I load second image an get pixel color? Gosu doesn't permit to get image info (only width and height).
Any ideas?
At the end I choose this GEM chunky_png, because it has no dependency from other gems or library and it's perfect to my needs:
#map_image = ChunkyPNG::Image.from_file('map_shape.png')
# Test pixel color
if #map_image[mouse_x - #main_image_x, mouse_y - #main_image_y] == ChunkyPNG::Color.rgb(255, 0,0)
# Do something
end
my goal: have a background image which occupies the full window of the display. And then on it, place image buttons which will be nicely centered on this window (buttons being arranged in grid).
The image is 1920X1080.
I have other code snippet which follows exactly the same sequence and the image appears in background. So totally baffled. But wanted to understand the logic correctly of this code/instead of relying on luck!..Note that on the other working code, I do both a place and grid of the background_label !. With this code the buttons don't appear at all.
when I use background_label(content....), the image does appear in the background with buttons in front, but in that case the whole display window is not occupied. The image just expands to fill the area occupied by button images.
root = Tk()
root.geometry("{0}x{1}+0+0".format(root.winfo_screenwidth(), root.winfo_screenheight()))
content = ttk.Frame(root, padding=(3,3,12,12))
print(root.winfo_screenwidth(), root.winfo_screenheight())
#prints as 1920 & 1080
#old background_image_file='waves1600x926.gif'
background_image_file='Lake.gif' #this is 1080X1920
background_image=PhotoImage(file=background_image_file)
background_label =ttk.Label(root,image=background_image) #tried content instead of root also
background_label.place(x=0, y=0,relwidth=1, relheight=1)
background_label.grid()
logos=['abc','cbs','nbc','fox','cnbc','amc','bet']
logobuttons=defaultdict(str)
logoimgs=defaultdict(str)
for logo in logos:
logoimgs[logo]=PhotoImage(file=LOGODIR+logo+'.gif')
logobuttons[logo]=ttk.Button(content,image=logoimgs[logo])
content.grid(column=0, row=0, sticky=(N,S,E,W))
col=0
row=0
maxcols=5
for logo in logos:
logobuttons[logo].grid(row=row,column=col,pady=5,padx=5)
if col == maxcols:
col=0
row=row+1
else:
col=col+1
root.mainloop()
When you use both place and grid, only the last one you call for a given widget has any effect. Thus, when you call background_label.grid() it totally negates the effect of background_label.place(...). In other words, you need to remove the call to grid for this widget.
If you want a background image, the best solution is to use place with a relative width and height of 1. You should also create the widget that contains the image first, so it is lowest in the stacking order. Though, you can always lower it later.
I am working on a task in which I have some objects like humans and toys and food which are foreground images/objects and I have a background image, for eg. like a park. I need to place foreground images/objects at specified locations over background image. I am using Matlab.
I was able to place a foreground image over background image, but its positioned in the center - not at a specified position.
How can I place foreground images at specified locations over background image using Matlab ?
My code is as follows:
figure1 = figure;
ax1 = axes('Parent',figure1);
ax2 = axes('Parent',figure1);
set(ax1,'Visible','off');
set(ax2,'Visible','off');
[a,map,alpha] = imread('foreground.png');
I = imshow(a,'Parent',ax2);
set(I,'AlphaData',alpha);
imshow('Background.jpg','Parent',ax1);
My images:
1) What I want:
2) What I'm getting:
Here is a simple solution using ginput in which the user clicks on a figure (here only once) and you fetch the coordinates of the point(s). In this example, there is a message box asking the user to select a point, then the foreground image is drawn over the background image. Notice that in my example I replace the pixels from the background image with those of the foreground. i.e. I do not use alpha and transparency. Hope that's fine for you; if not please tell me.
In the example, my 'background' image is the peppers image that ships with Matlab and the 'foreground' image is the pears image that also ships with Matlab. I use a small portion of the image for the demonstration.
Here is the code:
clear
clc
close all
%// Set up background image (peppers.png) and foreground image (part of
%// pears.png)
BackgroundImage = imread('peppers.png');
DummyForeground = imread('pears.png');
ForegroundImage = DummyForeground(50:200,50:200,:);
%// Get size of foreground image
[rowFore,colFore,channelFore] = size(ForegroundImage);
figure
imshow(BackgroundImage);
hMsg = msgbox('Select an anchor point for foreground image','modal');
uiwait(hMsg)
This looks like this:
%// Use ginput to prompt user to select a single point (i.e. the 1 in
%// brackets).
[x,y] = ginput(1);
Calling ginput results in the following:
x = round(x);
y = round(y);
%// Important!
hold on
%// Replace pixels of background image with foreground image.
BackgroundImage(y:y+rowFore-1,x:x+colFore-1,:) = ForegroundImage;
imshow(BackgroundImage);
And finally the background image with the foreground image:
Note: It looks like there is a shift between the cursor and the actual image placed; that happened when I took the screenshot haha it's not a bug :)
Now if you would like to add many images in the foreground, you could easily modify the code using multiple points for ginput, calling it like so:
[x,y] = ginput %// Indefinite # of points)
or [x,y] = ginput(SomeNumber) %// Any number you want
and add appropriate images for every point you selected.
Hope that was clear enough and it gets you started!
I'm have a picture box control and 2 Command Buttons. I have an image displayed inside the picture box.
Is it possible to zoom the image when the Zoom-in and Zoom out buttons are clicked?
Or I can even put a scroll bar. Is it possible to zoom the image according to the scroll bar movements?
I'm using VB 6.
I assume here that you are using BMP or JPG files here.
The simple scratch method is to place an Image control in the PictureBox, initially with the property Stretch = False. Initially, it would be in the top left hand corner. After setting the Picture property to your picture object, the Image control will be resized to fit the image. Save the original width and height of the control in variables. Now set Stretch = True. You can zoom in by resizing the image using
img.Move 0, 0, sngWidth * sngMagFactor, sngHeight * sngMagFactor
Where sngMaxFactor = 4! or however much you want to zoom by.
Restore back to original size by:
img.Move 0, 0, sngWidth, sngHeight
You can also pan the zoomed image by altering the Left and Top arguments in the Move() method.
It might be easiest to use two pic boxes, one inside the other. The 'outer' box can be thought of as a viewport into the 'inner' box, which you resize and position as needed. The effect will be the same but the coding is much simpler.