(re)detect number of monitors connected when disconnecting monitor - matlab

When multiple monitors are connected to my computer, I can detect them, and draw figures to them by setting the position according to the values obtained from
get(0, 'MonitorPositions')
However, when I disconnect a monitor while MATLAB is running, this property is not updated. I use distFig to handle the positioning of the figures, but since this property is not updated, sometimes the figures are drawn at the pixel locations that lay outside my screen (i.e. drawing on my disconnected monitor).
Restarting MATLAB solves the issue, but is there a way to re-detect the number of monitors connected?

I think I found a solution using JAVA:
I got the JAVA code from here: How do I get number of available screens?
Getting number of
get(0, 'MonitorPositions') keeps showing the same value, and the JAVA result changes:
%// Get local graphics environment
%GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
env = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment();
%// Returns an array of all of the screen GraphicsDevice objects.
%GraphicsDevice[] devices = env.getScreenDevices();
devices = env.getScreenDevices();
%numberOfScreens = devices.length;
numberOfScreens = length(devices)
I tested the code in Windows 10 OS.
In monitor duplicate mode, result is one monitor, and in extended mode 2.
When I unplug a monitor, the result is 1.
When unplugging all monitors the result is also 1 (it's not a perfect solution).

Related

How can I control which monitor plots are displayed on?

I have a 3 monitor Gentoo Linux system running MATLAB. MATLAB runs on the center monitor. I need MATLAB to generate plots on the left monitor but it always plots on the right monitor.
I believe this is at least partially caused by the non-standard way I have my monitors arranged physically - essentially 2,3,1:
>> get(0,'MonitorPositions')
ans =
1 1 1920 1080
-3839 1 1920 1080
-1919 1 1920 1080
Is there a way I can control this as a default within MATLAB?
You can set the default figure position on the root object like so:
set(0, 'DefaultFigurePosition', [-3839 1 1920 1080]);
This will create windows that fill the left monitor by default. However, this default will likely reset each time you restart MATLAB, so you will have to put it in your startup file if you want it to persist from session to session.
Note: The documentation for the 'MonitorPositions' property of the root object says this:
The first two elements in each row indicate the display location with respect to the origin point. The last two elements in each row indicate the display size. The origin point is the lower-left corner of the primary display.
If you change which monitor is used as the primary display, the relative coordinates in the left two columns will change, meaning you will have to change the position value in the above line of code. If you think the display setup may change often, or you will be running code on different monitor setups, then you can ensure plots will always appear on the left-most monitor by looking for the monitor position with the lowest value in the left column. Here's how you could do it (also incorporating the previous default window size and position within a monitor):
monitorPos = get(0, 'MonitorPositions');
figurePos = get(0, 'DefaultFigurePosition');
[~, leftIndex] = min(monitorPos(:, 1));
set(0, 'DefaultFigurePosition', figurePos + [monitorPos(leftIndex, 1:2)-1 0 0]);

how to position Matlab GUI window at top of screen?

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.

Same default figure position and size independent of screen resolution on different computers

I work with MATLAB on the right half of the screen, so I want figures to open on the left half of the screen. However, the figure height should be about the size of a default figure, so not the height of the screen. Also, I use MATLAB on different computers with variable screen sizes (pixels), so figure dimensions should depend on the screen size, but produce identical figures on screen. The figure dimensions and position are therefore dependent on the screen resolution, but the code generating the dimensions and position should be independent on it.
I've accomplished this with the code in my answer below, which I thought I'd share for anyone who finds this useful for their own setup.
The default MATLAB current folder can be set in MATLAB's preferences. I've set this to the network folder on all my MATLAB computers, this can also be a cloud folder of a cloud service, e.g. Dropbox. Then I put a file startup.m in that folder containing the following code.
ss = get(0,'screensize');
b = 7; % border around figures is 7 pixels wide
%TODO different for various operating systems and possibly configurations.
p = 0; % extra padding pixels from left edge of screen
if ispc
win = feature('getos');
i = (1:2) + regexp(win,'Windows ','end');
switch win(i)
case '10'
b = 0;
p = 2;
otherwise
% other cases will be added in the future
end
end
fwp = ss(3)/2-2*b-p; % figure width in pixels
b = b+p;
n = 5;
set(0,'defaultfigureposition',[b ss(4)/n, fwp, ss(4)*(1-2/n)])
clear
Now, every time I start MATLAB, it runs this script and it moves the default figures I create to the left half of the screen with a nice size (the axes are just a little wider than they are tall).
The figure's units are normalised, but they can be set to pixels or whatever measure you like as well. I hope someone will find this a useful script for their setup.
EDIT: I've update the script to keep the default figure units: pixels. This is necessary, because apps such as the curve fitting tool (cftool) or the Classification Learner (classificationLearner) and probably others are bugged with normalised figure units. Their (dialog) windows either don't show up (they are positioned outside your screen area) or are too small or too large.
EDIT 2: I've updated the script for compatibility with Windows 10. The figure windows now have a border of 1 pixel, instead of 7. Also, the figures are padded a bit to the right, because Windows 10 puts them too far to the left. Windows 10 is detected automatically.
TO DO: support additional operating systems (with detection), e.g. Mac, Linux. If you have such a system, please report the following in a comment:
Open MATLAB and copy paste the resulting string from the feature getos command here.
Position the figure against (not on or over) the left edge of the screen and against (not on or over) the right half of the screen and report the figure's position and outerposition here.

figure('Position',[x y width height]) won't go over height 800

I'm using an external monitor. My notebook has display of height 800 px, but monitor has over 1000 px. If I'm running the script on external monitor
screenSize = get(0,'MonitorPositions');
figureSize = screenSize(4);
figure('Position',[0 0 figureSize figureSize])
the size of the new figure won't go over the size of notebook display. Is there a way how to fix this?
EDIT
I have found that if I start MATLAB while having already set the external monitor as an output device, the script runs just ok. Is there any way how to reset settings, that are responsible, before running the skript?
You probably want:
figureSize = screenSize(monitorNumber,4);
As screenSize(4) will give you the 4th element in the matrix - same as screenSize = screenSize(:)
By default figures are displayed on the primary display. If you want to force Matlab to show figures on the external monitor, you need to set the DefaultFigurePosition to a value that is actually on the secondary monitor.
Therefore, let's say you create a figure and drag it on the external monitor. Then you can fetch the current position and set it to the default like so:
FigPos = get(gcf,'Position');
set(0, 'DefaultFigurePosition', FigPos);
Then figures will subsequently appear on the external monitor with a size that fits. That's not perfect since you need to create a figure, drag it and then delete it and it's only valid for your current session. However you can add the previous lines of code in your startup.m file to do it automatically.
Hope that helps somehow!

Simulink scope limit

I am running a simulink model in external simulation mode and am having the following problem: When I stop the simulation and get the data from the scope, it never saves more than the last 5,000 data points. I have tried unchecking "Limit data points to last:" checkbox, but that doesn't help. I also tried increasing that number to 10,000 but there was no difference in the number of points I was able to save.
I found that if I create a new model and set it to normal simulation mode, then I can save as many data points as I want. Can anyone explain why I might have this issue in external simulation but not normal simulation?
In external mode, data logging is effected by the Duration setting on the External Signal and Triggering panel of the External Mode Control Panel. Go to that panel and press the Help button for a description of Duration and how to change it