How to keep axes on top of uipanels?

12 visualizzazioni (ultimi 30 giorni)
Hi, I am developing a GUI in matlab. In my GUI there is an axis and an option to analyze data plotted on that axis. But to do that I need semi-transparent uipanels on top of the axis so that users can see the part of axis that is going to be analysed including the grids. Since matlab doesn't allow semi-transparent uipanels, I found a work around for completely transparent uipanels on undocumented matlab. As I can easily make axis transparent by setting it's Color property to 'none', I decided to make the uipanels under it, but no matter if I create the uipanels before or after creating the axis it always appears on top, I know this is how matlab does it, i.e. uipanels and uicontrols always remains on top of the axis, but I am wondering is there any hack/work-around that I can use to make the uipanel appear under the axis? Here is an example code of what I am trying:
F = figure;
Panel1 = uipanel('Parent',F,'BackgroundColor','y','Units','normalized','Position',[0 0 1 1]);
Panel2 = uipanel('Parent',Panel1,'BackgroundColor','g','Units','normalized','Position',[0.25 0.25 0.5 0.5]);
Axes1 = axes('Parent',Panel1,'GridColorMode','manual','GridColor','k','XGrid','on','YGrid','on',...
'GridLineStyle','--','NextPlot','add','Units','normalized','Position',[0 0 1 1]);
T = 1:1:10;
V = 10*rand(1,10);
PLot1 = plot(T,V,'Parent',Axes1);
Axes1.Color = 'none';
What I get is
PlotTest.png
I want this Panel2 (green coloured) to appear under the axis not on top of it. Is there any way this can be achieved?
I also tried another way of setting the BackgroundColor property of uipanel to transparent using the trick from undocumented matlab, and then place an axis on top of that uipanel. But doing so makes the uipanel opague back again. Here is the code for that:
F = figure;
Panel1 = uipanel('Parent',F,'BackgroundColor','y','Units','normalized','Position',[0 0 1 1]);
Panel2 = uipanel('Parent',Panel1,'BackgroundColor','g','Units','normalized','Position',[0.25 0.25 0.5 0.5]);
Panel3 = uipanel('Parent',Panel1,'BackgroundColor','r','Units','normalized','Position',[0 0 1 1]);
Axes1 = axes('Parent',Panel3,'GridColorMode','manual','GridColor','k','XGrid','on','YGrid','on',...
'GridLineStyle','--','NextPlot','add','Units','normalized','Position',[0 0 1 1]);
T = 1:1:10;
V = 10*rand(1,10);
PLot1 = plot(T,V,'Parent',Axes1);
Axes1.Color = 'none';
% Making Panel3 Transparent
jPanel = Panel3.JavaFrame.getPrintableComponent;
jPanel.setOpaque(false)
jPanel.getParent.setOpaque(false)
jPanel.getComponent(0).setOpaque(false)
jPanel.repaint
And the result of above code
PlotTest2.PNG
If there is any way I can make the uipanel appear under the axis then please let me know, any help will be highly appriciated. Thank you :)

Risposta accettata

Chaitanya Jha
Chaitanya Jha il 5 Dic 2019
I was able to figure out the answer myself. The simple solution is to use Annotations:
Specifically a rectance annotation:
This has a property called FaceAlpha which changes its transparency and these annotations can be placed on uipanels of figures. Below is the code that works as I desire:
F = figure('menubar','none','numbertitle','off','Color','w');
P = uipanel('Parent',F,'BorderType','none','BackgroundColor','g',...
'Units','normalized','Position',[0 0 1 1]);
A = axes('Parent',P,'GridColorMode','manual','GridColor','k',...
'XGrid','on','YGrid','on','GridLineStyle','--','NextPlot',...
'add','Units','normalized','Position',[0 0 1 1]);
T = 1:1:10;
V = 10*rand(1,10);
plot(T,V,'Parent',A,'Color','r');
An = annotation(P,'rectangle',[0.25 0.25 0.5 0.5],'FaceColor','b',...
'FaceAlpha',0.5,'LineStyle','none');
And the outcome of this code is:
PlotTest3.PNG
This is exactly what I need, a semi-transparent thing on top of axis to signify the area of plot that will be analysed.

Più risposte (2)

Yair Altman
Yair Altman il 5 Dic 2019
You can also use a semi-tranparent patch. Patches are children of axes, so they move around with the axes if you zoom or pan, and are more light-weight objects than annotations. Patches have a FaceAlpha property that can be set to enable partial transparance.

Yair Altman
Yair Altman il 4 Dic 2019
You had a few errors in your code: first, you made Panel3 transparent instead of Panel2. Secondly, you need to create Panel2 inside Panel3, not Panel1. Below is the corrected code that apparently does what you wanted (I modified the position values a bit so that you can see what is on top of what).
Reference on making uipanels transparent: https://undocumentedmatlab.com/articles/transparent-uipanels
% Create the figure, main panels and axes
f = figure('menubar','none', 'toolbar','none');
hPanel1 = uipanel('Parent',f,'BackgroundColor','y','Units','normalized','Position',[0 0 1 1]);
hPanel3 = uipanel('Parent',hPanel1,'BackgroundColor','r','Units','normalized','Position',[.1,.1,.8,.8]);
hAx = axes('Parent',hPanel3,'GridColorMode','manual','GridColor','k','XGrid','on','YGrid','on',...
'GridLineStyle','--','NextPlot','add','Units','normalized','Position',[.1,.1,.8,.8]);
T = 1:1:10;
V = 10*rand(1,10);
plot(hAx, T, V);
hAx.Color = 'none';
drawnow; pause(.3);
% Create Panel2 *on top of* the axes (hPanel3)
hPanel2 = uipanel('Parent',hPanel3,'BackgroundColor','g','Units','normalized','Position',[0.25 0.25 0.5 0.5]);
uicontrol(hPanel2, 'String','start', 'Pos',[ 20,50,60,40]);
uicontrol(hPanel2, 'String','stop', 'Pos',[130,50,60,40]);
% Make Panel2 transparent
jPanel = hPanel2.JavaFrame.getPrintableComponent;
jPanel.setOpaque(false)
jPanel.getParent.setOpaque(false)
jPanel.getComponent(0).setOpaque(false)
jPanel.repaint
test1.png
In the past it used to be possible to make Java containers (such as the JPanel which is the basis for uipanel) semi-tranparent (translucent), by setting an opacity level (0.0 to 1.0). Unfortunately, the underlying mechanism changed when Matlab switched Java versions some years ago. It might still be possible to do it, but I never bothered to look into it - users who are not afraid to get their hands dirty with Java Swing GUI are welcome to pick up this challenge.
More information on this:
  1 Commento
Chaitanya Jha
Chaitanya Jha il 5 Dic 2019
Hi Yair,
Thanks for your input. I know I could have done what you said above but it does not solve my problem because I do not want to place anything on the panel which you made transparent, but rather that panel is used to signify the area in the plot which will be analysed. It is for this reason that I want it to be semi-transparent so that plot is visible under the panel.
In your approach the panels are top of the plot and is completely transparent, the borders are visible but that will be no good as soon as I have 3 or 4 of of these panels signifying different regions of the plot to be analysed.
Since I cannot make panels semi-transparent panels my approach was to create panels under the axis and then make the axis transparent so that the plot is visible while the area of the panel under it shows the area of the plot that will be analysed. This is why I made Panel2 non-transparent and placed it on Panel1 and not Panel3.
It took me a while but I was able to figure out a perfect solution for my problem. See my answer below, and thanks so much for your help.
Chaitanya

Accedi per commentare.

Categorie

Scopri di più su Graphics Object Properties in Help Center e File Exchange

Prodotti


Release

R2018b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by