I have a troubling problem that I've been trying to figure out for quite a while now and I just have no clue why it's happening. I have a self-coded GUI and I have a panel on the main GUI figure. On this panel I have an axes and whenever I plot a bar graph on that axes and try to edit its view with either yLim() or axis(), the axes will be resized to the dimensions I want, but the bar graph will not chop off at the edge of the axes and it will continue to run off the page. After playing around with it for a while in debug mode, I have found out that if I change the axes' parent from the panel it's on to the main figure, the bar graph will properly display only what is inside the axes borders like I want it to. I don't want to use changing the axes' parent as a permanent solution since I have several different panels I want to go between and having an axes on the main figure instead of the panel wouldn't work but I'd like to know if anybody knows why this is happening and how I can fix it.
For example, this code produces the problem I'm experiencing:
mainFig = figure('Units','characters',...
'Position',[40 5 200 50],...
'Color',[100/255 145/255 209/255]);
axesPanel = uipanel('bordertype','etchedin',...
'Parent',mainFig,...
'Title','Axes Panel');
mainAxes = axes('parent',axesPanel,...
'Units','characters');
bar(mainAxes,1:10,1:10)
ylim(mainAxes,[6 10])
And if the axes' parent is changed to be the figure, the problem doesn't exist. This line of code does that:
set(mainAxes,'parent',mainFig)
Thanks for any help or information as to why this is happening!
Just in case anybody else was having this same problem, I contacted MATLAB Technical Support and I was told that this was a bug on MATLAB's end that is being fixed in the next release(R2014b). They said that if you are having the problem I described in my original question, that in order to make the bar graph appear within the axes' boundaries at the moment, that you can edit the figure's 'Renderer' property and set it to either 'opengl' or 'zbuffer'. I have tested this and both options work so hopefully that helps :)
And just for extra clarification if it is needed, all I needed to change from my original code was:
mainFig = figure('Units','characters',...
'Position',[40 5 200 50],...
'Color',[100/255 145/255 209/255]);
To this:
mainFig = figure('Units','characters',...
'Renderer','opengl',...
'Position',[40 5 200 50],...
'Color',[100/255 145/255 209/255]);
And now the bar graph behaves as it should.
Related
I used Matlab GUIDE to create a GUI.
It is displayed mid-screen.
How can I position it at the top of the screen; so that the top edge of the GUI window is at top of screen.
It will be used on different Windows 7 computers with different screen resolutions.
I tried to set hObject.Position(2) but it doesn't do what I want.
I think the simplest way would be to use movegui in the OpeningFcn of your GUI with the appropriate argument, i.e. using either 'north', 'northeast' or 'northwest'.
The calling syntax is quite simple, using the handles to the figure created. In GUIDE, the default name for figures is "figure1", so in your case the code would look like this (unless you changed the figure's name):
movegui(handles.figure1,'northwest') %// or whatever
Note that movegui calls the following 3 functions to get the screen size and monitor positions/units:
screensize = get(0, 'ScreenSize');
monitors = get(0,'MonitorPositions');
old0units = get(0, 'Units');
So you could do the same to make the calculations yourself in order to place the figure precisely where you want if the above solution is not sufficient for you.
Hi everyone and thanks in advance for all your help.
I'm currently working on a UI in matlab that includes 4 differents axes to show various info. Basicly, I have MRI data (so 3D data) that I want to show. I use 1 axe to show 3 perpendicular plane that split the data at its center (axeMain), and 3 other axes that shows the planes individually (axeX,axeY and axeZ). I have a main axe on wich I want to make rotations possible (only on the main axis system) and I want to be able to select coordinate on the 3 other axe (those with 1 plane only). I also unable translations but that is out of scope for my problem.
So basicly, I have no problem selecting my coordinates (using the buttondownfcn on my planes) on all of the 3 axes and I also have no problem using rotate3D on the mainAxe. HOWEVER, if I try to have both to work at the same time, the buttondownfcn doesn't work anymore. I don't understand why it's doing this (I have some ideas but that's about it) and I have no idea how to work around it. Basicly my code for those functions are like this :
rotate3d(handles.axisMain);
%some other code, setting up other UI stuff
%allow selection on the 3 static plains.
set([handles.axeX,handles.axeY,handles.axeZ], 'buttondownfcn', #getCoord);
So my question is basicly : why wont those 2 functions don't work together and how to work around that problem, ideally with minimal code change?
Thanks.
EDIT : this is a print screen of my current interface. I want to be able to select coordinate using ONLY on the 3 last axes (containing only 1 plane in each of them). I also want to be able to rotate images ONLY on the first axe (the one with 3 planes). Hope this clarify.
I would also like to note this : following my tests, I found that the mouse click would not raise at all if the rotate3D is activated. The problem is not in the logic I use to get the coordinates itself, but in the click event not being fired.
Also, I am aware that the event is not on the surface that I try to print. The actual code is like this :
set(h, 'buttondownfcn', #getCoord);
set(h,'HitTest','on');
where h is the handle of a surface and each surfaces are processed this way.
I have found the exact solution!
Exploring the code for rotate3d(hAxe,'on') , i have found that they key line is getuimode(hFig,'Exploration.Rotate3d') wich returns uitools.uimode that contains ButtonDownFilter and ModeStateData methods.
Finally i have solved the problem in the following way:
rotate3d(hAxe,'on')
uiMode = getuimode(hFig,'Exploration.Rotate3d');
uiMode.ButtonDownFilter = #mycallback;
where:
hAxe is the handle to the axes object
hFig is the handle to the figure object
#mycallback is the callback that lets buttondownfcn and rotate3d works together as in the example of Matlab's help
So, you have to tag the object that you want to not be ignored:
set(hAxe,'tag','DoNotIgnore')
And write the callback:
function [flag] = mycallback(obj,event_obj)
% If the tag of the object is 'DoNotIgnore', then return true
objTag = obj.Tag;
if strcmpi(objTag,'DoNotIgnore')
flag = true;
else
flag = false;
end
maybe
set(handles.axisMain, 'buttondownfcn', #getCoord);
I'm using TabPanel for building my GUI. The problem is, that when I'm drawing rectangle it appears outside of my axes. Problem does not exist when not using TabPanel.
I was testing 'clipping' parameter, but my object is still outside axes (fig).
Any hints?
thanks!
I have good news and bad news. (There is no answer all over the internet, I just saw unanswered requests like this one).
I had exactly the same problem. After checking, the problem is actually restrained to MARKERS (so either marker not set to none in the case of plots, or scatters). If I only plot lines, it stays clipped.
The issues is the renderer of the figure in which your plot is. You have to set it to "painter" or "zbuffer" and not "openGL". Sadly only the latter lets you plot transparent images :( . I think Matlab should fix this issue so we can have both unclipped markers and transparent images in the same figure...
K>> get(handles.output,'Renderer')
ans =
OpenGL
K>> set(handles.output,'Renderer','painter')
Yanis
edit: the solving might be similar for rectangles I hope.
I would like to add text annotation to a figure from a GUI made with GUIDE. First I plot some data, than when the user clicks on a checkbox I call the text function in the event handler like this:
text(obj.XData(q), obj.YData(q)+10, int2str(q), 'Units', 'pixels');
obj is the line object itself, q is a counter for each point in the plot. It runs without errors, but nothing happens. I suppose I should 'refresh' the axis somehow, but refresh command doesn't help and I haven't found anything in the documentation.
Edit: I have found out that my code was wrong: pixel units correspond to a coordinate system where the origin is the lower-left corner of my axis control, what is not the same as my data coordinate system. I fixed this problem with ds2nfu, and when I paint before plotting everything is fine. But after plotting I see nothing. Is it possible that there is some kind of z-order problem with annotations?
As I mentioned in the comments, you should use the normalized units to place things in the same coordinate system as the data.
Now for the other problem. I'm not sure if this is a z-order issue, but if it is, you can bring the text to the front using UISTACK:
hText = text(x,y,'str');
uistack(hText, 'top')
I have a question about the values returned by getPosition. Below is my code. It lets the user set 10 points on a given image:
figure ,imshow(im);
colorArray=['y','m','c','r','g','b','w','k','y','m','c'];
pointArray = cell(1,10);
% Construct boundary constraint function
fcn = makeConstrainToRectFcn('impoint',get(gca,'XLim'),get(gca,'YLim'));
for i = 1:10
p = impoint(gca);
% Enforce boundary constraint function using setPositionConstraintFcn
setPositionConstraintFcn(p,fcn);
setColor(p,colorArray(1,i));
pointArray{i}=p;
getPosition(p)
end
When I start to set points on the image I get results like [675.000 538.000], which means that the x part of the coordinate is 675 and the y part is 538, right? This is what the MATLAB documentation says, but since the image is 576*120 (as displayed in the window) this is not logical.
It seemed to me like, somehow, getPosition returns the y coordinate first. I need some clarification on this.
Thanks for help
I just tried running your code in MATLAB 7.8.0 (R2009a) and had no problems with image sizes of either 576-by-120 or 120-by-576 (I was unsure which orientation you were using). If I left click inside the image, it places a new movable point. It did not allow me to place any points outside the image.
One small bug I found was that if you left-click in the image, then drag the mouse pointer outside the image while still holding the left button down, it will place the movable point outside the image and won't display it, displaying a set of coordinates that are not clipped to the axes rectangle.
I'm not sure of what could be your problem. Perhaps it's a bug with whatever MATLAB version you are using. I would suggest either restarting MATLAB, or clearing all variables from the workspace (except for the image data im).
Might be worth checking to see which renderer you are using (Painter or OpenGL), a colleague showed me some wierd behaviour with point picking when using the OpenGL renderer which went away when using the Painter renderer.
Your code uses the Image Processing Toolbox, which I don't have, so this is speculation. The coordinate system is probably set to the figure window (or maybe even the screen), not the image.
To test this, try clicking points outside the image to see if you can find the origin.