Discover MakerZone

MATLAB and Simulink resources for Arduino, LEGO, and Raspberry Pi

Learn more

Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply Today

Thread Subject:
Looped inset plot

Subject: Looped inset plot

From: Josh

Date: 16 Jan, 2013 04:23:11

Message: 1 of 10

I need help trying to use an inset plot in a loop.

What I have is a scatter plot and a box plot.
This is a demonstration of trimming outliers, and not meant to pass peer review.

The script starts with all the data in a scatter plot, and then trims one outlier on each pass through the loop, pauses a moment, and then does it again until all the outliers are removed. An lsline and some other information like R^2 is displayed in the plot as well.
A box plot runs at the same time.

I would like to inset the box plot into the scatter plot.

The problem with all the solutions I have found is that on the second pass through, it puts the scatter plot into the inset area, rather than as the main plot. When I try to use subplots, the second plot is opaque the main plot underneath is not visible.

Thank you in advance

Subject: Looped inset plot

From: dpb

Date: 16 Jan, 2013 14:18:07

Message: 2 of 10

On 1/15/2013 10:23 PM, Josh wrote:
> I need help trying to use an inset plot in a loop.
>
> What I have is a scatter plot and a box plot.
...

> I would like to inset the box plot into the scatter plot.
>
> The problem with all the solutions I have found is that on the second
> pass through, it puts the scatter plot into the inset area, rather than
> as the main plot. When I try to use subplots, the second plot is opaque
> the main plot underneath is not visible.
...

Sounds like you're not switching back to the other plot to make it the
current axis.

_Minimal_ example of your loop would help...

--

Subject: Looped inset plot

From: Josh

Date: 16 Jan, 2013 15:32:08

Message: 3 of 10

dpb <none@non.net> wrote in message <kd6cql$g3s$1@speranza.aioe.org>...
> On 1/15/2013 10:23 PM, Josh wrote:
> > I need help trying to use an inset plot in a loop.
> >
> > What I have is a scatter plot and a box plot.
> ...
>
> > I would like to inset the box plot into the scatter plot.
> >
> > The problem with all the solutions I have found is that on the second
> > pass through, it puts the scatter plot into the inset area, rather than
> > as the main plot. When I try to use subplots, the second plot is opaque
> > the main plot underneath is not visible.
> ...
>
> Sounds like you're not switching back to the other plot to make it the
> current axis.
>
> _Minimal_ example of your loop would help...
>
> --
Thanks for replying,
Here is the basic code with some modification for simplicity and a random data set instead of my actual data.

x = sort(abs(randn(1,100)));
xi = chi2pdf(x,2);
for i = 1:length(x)
    y(i) = xi(i)*abs(randn(1));
end

while true
    subplot(1,2,1)
    boxplot(y)
    subplot(1,2,2)
    plot(x,y,'*')
    lsline
    title(['R^2 = ',num2str(corr(x',y')^2)])
    pause(1)
    m = mean(y);
    outlier = quantile(y,.75) + 1.5*iqr(y);
    z = find(y >= outlier);
    if isempty(z) == false
        [v ind] = sort(y,'descend');
    else
        break
    end
    y(ind(1)) = [];
    x(ind(1)) = [];
end
It is meant to be a demonstration of several concepts, mainly what happens when methods intended for Normal distributions are used with non-Normal data (abuse of the central limit theorem), and why removal of any outlier must be well justified.
I would like the boxplot to be inset inside the scatter plot.

Thank you again

Subject: Looped inset plot

From: dpb

Date: 16 Jan, 2013 19:01:05

Message: 4 of 10

On 1/16/2013 9:32 AM, Josh wrote:
> dpb <none@non.net> wrote in message <kd6cql$g3s$1@speranza.aioe.org>...
>> On 1/15/2013 10:23 PM, Josh wrote:
>> > I need help trying to use an inset plot in a loop.
>> >
>> > What I have is a scatter plot and a box plot.
>> ...
>>
>> > I would like to inset the box plot into the scatter plot.
>> >
>> > The problem with all the solutions I have found is that on the second
>> > pass through, it puts the scatter plot into the inset area, rather than
>> > as the main plot. When I try to use subplots, the second plot is opaque
>> > the main plot underneath is not visible.
>> ...
>>
>> Sounds like you're not switching back to the other plot to make it the
>> current axis.
>>
>> _Minimal_ example of your loop would help...
>>
>> --
> Thanks for replying,
> Here is the basic code with some modification for simplicity and a
> random data set instead of my actual data.
>
> x = sort(abs(randn(1,100)));
> xi = chi2pdf(x,2);
> for i = 1:length(x)
> y(i) = xi(i)*abs(randn(1));
> end
>
> while true
> subplot(1,2,1)
> boxplot(y)
> subplot(1,2,2)
> plot(x,y,'*')
...

Play around w/ the following at some point when you've got some data...

 >> figure
 >> h1=axes; % create a main axes object
 >> plot(h1,x,y,'*') % plot into it
 >> h2=axes('pos',[.55 .25 .30 .50]); % now an inset set of axes
 >> boxplot(h2,y) % and the boxplot therein...

Now, each loop thru, pick the proper set of axes.

You'll have to "salt to suit" dimensions and perhaps deal w/ finding an
"open-enough" space, etc., etc., etc., ... but it's the basic way to get
what I think is the effect you're after.

--

Subject: Looped inset plot

From: dpb

Date: 16 Jan, 2013 19:10:09

Message: 5 of 10

On 1/16/2013 1:01 PM, dpb wrote:
...

> Play around w/ the following at some point when you've got some data...
>
> >> figure
> >> h1=axes; % create a main axes object
> >> plot(h1,x,y,'*') % plot into it
> >> h2=axes('pos',[.55 .25 .30 .50]); % now an inset set of axes
> >> boxplot(h2,y) % and the boxplot therein...
>
> Now, each loop thru, pick the proper set of axes.
>
...

Oh, meant to add--search the documentation section on 'Enhanced
Plotting' or similar section title for animation of plots techniques.
You'll be able to avoid the flicker of the update and speed it up as
well by simply replacing the dataset in the plot() and I presume you can
also do similar inside boxplot altho I've not done any handle-diving
there to determine what that entails with it.

--

Subject: Looped inset plot

From: Josh

Date: 17 Jan, 2013 23:50:09

Message: 6 of 10

dpb <none@non.net> wrote in message <kd6tu5$v3u$2@speranza.aioe.org>...
> On 1/16/2013 1:01 PM, dpb wrote:
> ...
>
> > Play around w/ the following at some point when you've got some data...
> >
> > >> figure
> > >> h1=axes; % create a main axes object
> > >> plot(h1,x,y,'*') % plot into it
> > >> h2=axes('pos',[.55 .25 .30 .50]); % now an inset set of axes
> > >> boxplot(h2,y) % and the boxplot therein...
> >
> > Now, each loop thru, pick the proper set of axes.
> >
> ...
>
> Oh, meant to add--search the documentation section on 'Enhanced
> Plotting' or similar section title for animation of plots techniques.
> You'll be able to avoid the flicker of the update and speed it up as
> well by simply replacing the dataset in the plot() and I presume you can
> also do similar inside boxplot altho I've not done any handle-diving
> there to determine what that entails with it.
>
> --

Thank you for the help. It turned out to be not easily workable. There was a host of problems including the y-axis on the main plot not clearing, not being able to include an lsline, inserted text did not work properly, etc.

I did finally find something that worked with a bit of tweaking. I am including the code incase any one else has a similar issue and wants complete working code to play with.
The one issue with this is that the text that insets and updates with each refresh is tied to the inset plot rather than the main plot. It was fine for this, but could be a problem in other cases.

As I said this is meant to be a demonstration of several things, and is also meant to create discussion.


% Source: "Gun homicides and gun ownership listed by country"
% Simon Rogers, The Gaurdian, 22 July, 2013
% http://www.guardian.co.uk/news/datablog/2012/jul/22/gun-homicides-ownership-world-list
% Data extracted from .xls spreadsheet and should be taken as "essentially" accurate
clear A B C
%gun/per g_deaths/person
A =...
    [0.303 0.00000000000000000
    0.248 0.00000000000000000
    0.119 0.00000000000000000
    0.014 0.00000000000000000
    0.004 0.00000000000000000
    0.006 0.00000009295774648
    0.007 0.00000021875000000
    0.005 0.00000022727272727
    0.011 0.00000030196078431
    0.007 0.00000031111111111
    0.192 0.00000036915977697
    0.313 0.00000044714285714
    0.312 0.00000057473684211
    0.055 0.00000068750000000
    0.062 0.00000074764705882
    0.076 0.00000080000000000
    0.147 0.00000081666666667
    0.073 0.00000087600000000
    0.013 0.00000089215686275
    0.135 0.00000100000000000
    0.038 0.00000105555555556
    0.019 0.00000114000000000
    0.073 0.00000123380281690
    0.035 0.00000132758620690
    0.150 0.00000147540983607
    0.226 0.00000171027027027
    0.083 0.00000184444444444
    0.071 0.00000189333333333
    0.303 0.00000191496000000
    0.163 0.00000203750000000
    0.104 0.00000208000000000
    0.066 0.00000212903225806
    0.304 0.00000218880000000
    0.092 0.00000224390243902
    0.010 0.00000230769230769
    0.048 0.00000237798165138
    0.015 0.00000259459459459
    0.225 0.00000261000000000
    0.120 0.00000276923076923
    0.042 0.00000282404347826
    0.219 0.00000288157894737
    0.125 0.00000296052631579
    0.008 0.00000327804878049
    0.190 0.00000339285714286
    0.217 0.00000388315789474
    0.085 0.00000415555555556
    0.316 0.00000417571428571
    0.039 0.00000420588235294
    0.014 0.00000434000000000
    0.453 0.00000453000000000
    0.173 0.00000461333333333
    0.115 0.00000474603174603
    0.086 0.00000501666666667
    0.073 0.00000530909090909
    0.016 0.00000533333333333
    0.308 0.00000535517587940
    0.378 0.00000557704918033
    0.009 0.00000560000000000
    0.153 0.00000655714285714
    0.062 0.00000658750000000
    0.364 0.00000661818181818
    0.172 0.00000668888888889
    0.119 0.00000708900000000
    0.125 0.00000743055555556
    0.457 0.00000766147058824
    0.044 0.00000776827586207
    0.035 0.00000834473684211
    0.210 0.00000868000000000
    0.014 0.00000980000000000
    0.005 0.00001040000000000
    0.089 0.00001083478260870
    0.241 0.00001229591836735
    0.017 0.00001288909090909
    0.043 0.00001340166666667
    0.013 0.00001365000000000
    0.015 0.00001455000000000
    0.065 0.00001547619047619
    0.086 0.00001783703703704
    0.107 0.00002158342857143
    0.006 0.00002258823529412
    0.318 0.00002688545454545
    0.034 0.00002856000000000
    0.078 0.00002971428571429
    0.888 0.00003008017777778
    0.102 0.00003093569620253
    0.099 0.00004627674418605
    0.013 0.00006289189189189
    0.044 0.00006578000000000
    0.077 0.00006588860759494
    0.170 0.00007922000000000
    0.047 0.00008856487179487
    0.150 0.00010944193548387
    0.146 0.00011281818181818
    0.053 0.00016211764705882
    0.217 0.00017639000000000
    0.127 0.00017756521008403
    0.051 0.00018337333333333
    0.080 0.00018694339622642
    0.188 0.00018975466666667
    0.100 0.00023448275862069
    0.059 0.00027400037037037
    0.016 0.00027809523809524
    0.058 0.00035467000000000
    0.131 0.00039768424242424
    0.081 0.00040688372093023
    0.107 0.00041730000000000
    0.062 0.00064492400000000];

B=[{'Iceland'}
    {'Bahrain'}
    {'Malta'}
    {'Brunei'}
    {'Solomon Islands'}
    {'Japan'}
    {'Romania'}
    {'Singapore'}
    {'Korea, South'}
    {'Lithuania'}
    {'Qatar'}
    {'Norway'}
    {'France'}
    {'Hungary'}
    {'England and Wales'}
    {'Algeria'}
    {'Mauritius'}
    {'Israel'}
    {'Poland'}
    {'Slovenia'}
    {'Turkmenistan'}
    {'Mongolia'}
    {'Belarus'}
    {'Azerbaijan'}
    {'Australia'}
    {'New Zealand'}
    {'Slovakia'}
    {'Moldova'}
    {'Germany'}
    {'Czech Republic'}
    {'Spain'}
    {'Ukraine'}
    {'Austria'}
    {'Estonia'}
    {'Tajikistan'}
    {'Cuba'}
    {'Malaysia'}
    {'Greece'}
    {'Denmark'}
    {'India'}
    {'Northern Ireland'}
    {'Armenia'}
    {'Nepal'}
    {'Latvia'}
    {'Croatia'}
    {'Portugal'}
    {'Sweden'}
    {'Netherlands'}
    {'Congo, Dem Rep'}
    {'Finland'}
    {'Bosnia and Herzegovina'}
    {'Jordan'}
    {'Ireland'}
    {'Georgia'}
    {'Liberia'}
    {'Canada'}
    {'Serbia'}
    {'Kyrgyzstan'}
    {'Luxembourg'}
    {'Bulgaria'}
    {'Cyprus'}
    {'Belgium'}
    {'Italy'}
    {'Turkey'}
    {'Switzerland'}
    {'Taiwan'}
    {'Egypt'}
    {'Lebanon'}
    {'Uganda'}
    {'Bangladesh'}
    {'Zambia'}
    {'Macedonia'}
    {'Vietnam'}
    {'Cambodia'}
    {'Kazakhstan'}
    {'Sri Lanka'}
    {'Maldives'}
    {'Albania'}
    {'Chile'}
    {'Sierra Leone'}
    {'Uruguay'}
    {'West Bank & Gaza'}
    {'Barbados'}
    {'United States'}
    {'Argentina'}
    {'Costa Rica'}
    {'Ecuador'}
    {'Zimbabwe'}
    {'Nicaragua'}
    {'Paraguay'}
    {'Philippines'}
    {'Mexico'}
    {'Guyana'}
    {'Bahamas'}
    {'Panama'}
    {'South Africa'}
    {'Dominican Republic'}
    {'Brazil'}
    {'Peru'}
    {'Belize'}
    {'Colombia'}
    {'Trinidad and Tobago'}
    {'El Salvador'}
    {'Guatemala'}
    {'Jamaica'}
    {'Venezuela'}
    {'Honduras'}];
c = 1;
C(1,1)=[{num2str(corr(A(:,1),A(:,2))^2)}];

while true
    subplot(1,1,1)
    plot(A(:,1),A(:,2),'*'),%hold on
    title('Scatter plot and Box Plot of Gun Density vs. Gun Deaths')
    xlabel('Gun Density')
    ylabel('Shooting Deaths per Person')
    lsline
    xt = get(gca,'xtick');
    yt = get(gca,'ytick');
    axes('pos',[.61 .55 .1 .3])
    
    boxplot(A(:,2),'widths',1/2)
    set(gca,'xticklabel','[]')
    
    text(1.6,1.2*max(A(:,2)),[C],'verticalalignment','top')
    text(1.25,1.23*max(A(:,2)),'R^2 = ','verticalalignment','top')
    my = mean(A(:,2));
    outlier = quantile(A(:,2),.75) + 1.5*iqr(A(:,2));
    z = find(A(:,2) >= outlier);
    if isempty(z) == false
        [v ind] = sort(A(:,2),'descend');
    else
        break
    end
    r(c) = corr(A(:,1),A(:,2));
    C(1,1)=[{num2str(r(c)^2)}];
    C(c+1,1) = B(ind(1));
    c = c+1;
    A(ind(1),:) = [];
    B(ind(1)) = [];
    
    pause(1)
end

Subject: Looped inset plot

From: dpb

Date: 18 Jan, 2013 13:38:35

Message: 7 of 10

On 1/17/2013 5:50 PM, Josh wrote:
> dpb <none@non.net> wrote in message <kd6tu5$v3u$2@speranza.aioe.org>...
>> On 1/16/2013 1:01 PM, dpb wrote:
>> ...
>>
>> > Play around w/ the following at some point when you've got some data...
>> >
>> > >> figure
>> > >> h1=axes; % create a main axes object
>> > >> plot(h1,x,y,'*') % plot into it
>> > >> h2=axes('pos',[.55 .25 .30 .50]); % now an inset set of axes
>> > >> boxplot(h2,y) % and the boxplot therein...
>> >
>> > Now, each loop thru, pick the proper set of axes.
>> >

...

> Thank you for the help. It turned out to be not easily workable. There
> was a host of problems including the y-axis on the main plot not
> clearing, not being able to include an lsline, inserted text did not
> work properly, etc.
>
...


Don't understand the above...guess it comes down to the "easily" part,
but can't think it's not relatively simple for any/all of the above.

Certainly would help to see what your code that didn't please looked
like...if 'hold on' is not in action the plot() should change the axis
to match the new data if use it, if not using plot() but replacing data
one does need to rescale if necessary of course. I was presuming the
data would be of roughly same magnitude but if not then that's a need,
certainly. I can't understand why you say you couldn't include a
ls-line nor why text wasn't "working properly" though.

--

Subject: Looped inset plot

From: Josh

Date: 18 Jan, 2013 17:49:08

Message: 8 of 10

dpb <none@non.net> wrote in message <kdbj8g$tgi$1@speranza.aioe.org>...
> On 1/17/2013 5:50 PM, Josh wrote:
> > dpb <none@non.net> wrote in message <kd6tu5$v3u$2@speranza.aioe.org>...
> >> On 1/16/2013 1:01 PM, dpb wrote:
> >> ...
> >>
> >> > Play around w/ the following at some point when you've got some data...
> >> >
> >> > >> figure
> >> > >> h1=axes; % create a main axes object
> >> > >> plot(h1,x,y,'*') % plot into it
> >> > >> h2=axes('pos',[.55 .25 .30 .50]); % now an inset set of axes
> >> > >> boxplot(h2,y) % and the boxplot therein...
> >> >
> >> > Now, each loop thru, pick the proper set of axes.
> >> >
>
> ...
>
> > Thank you for the help. It turned out to be not easily workable. There
> > was a host of problems including the y-axis on the main plot not
> > clearing, not being able to include an lsline, inserted text did not
> > work properly, etc.
> >
> ...
>
>
> Don't understand the above...guess it comes down to the "easily" part,
> but can't think it's not relatively simple for any/all of the above.
>
> Certainly would help to see what your code that didn't please looked
> like...if 'hold on' is not in action the plot() should change the axis
> to match the new data if use it, if not using plot() but replacing data
> one does need to rescale if necessary of course. I was presuming the
> data would be of roughly same magnitude but if not then that's a need,
> certainly. I can't understand why you say you couldn't include a
> ls-line nor why text wasn't "working properly" though.
>
> --
here is a working example of what happens. I've tried various variations of this.
If you run this, you will get an error for the lsline, "Warning: No allowed line types or scatterplots found. Nothing done." The text HI does not appear as well, and if you run the text command after the script is done to see where it should actually appear, it seems to be linked to the inset plots lower left corner. Also, the y axis tickmarks do not refresh, and end up super imposed upon each other.

Thanks again for the help. I have run into this problem with several models, and I would love to have a nice clean way of running looped plots with insets.

clear all
x = sort(abs(randn(1,100)));
xi = chi2pdf(x,2);
for i = 1:length(x)
    y(i) = xi(i)*abs(randn(1));
end
figure(1)
h1 = axes;
h2 = axes('pos',[.55 .4 .2 .4]);

while true
    plot(h1,x,y,'*')
    title(['R^2 = ',num2str(corr(x',y')^2)])
    lsline
    text(0,0,'HI!')
    
    boxplot(h2,y)

    pause(1)
    m = mean(y);
    outlier = quantile(y,.75) + 1.5*iqr(y);
    z = find(y >= outlier);
    if isempty(z) == false
        [v ind] = sort(y,'descend');
    else
        break
    end
    y(ind(1)) = [];
    x(ind(1)) = [];
     
end

Subject: Looped inset plot

From: dpb

Date: 18 Jan, 2013 20:55:24

Message: 9 of 10

On 1/18/2013 11:49 AM, Josh wrote:
> dpb <none@non.net> wrote in message <kdbj8g$tgi$1@speranza.aioe.org>...
...

>> Certainly would help to see what your code that didn't please looked
>> like...if 'hold on' is not in action the plot() should change the axis
...

> here is a working example of what happens. I've tried various variations
> of this.
> If you run this, you will get an error for the lsline, "Warning: No
> allowed line types or scatterplots found. Nothing done." The text HI
> does not appear as well, and if you run the text command after the
> script is done to see where it should actually appear, it seems to be
> linked to the inset plots lower left corner. Also, the y axis tickmarks
> do not refresh, and end up super imposed upon each other.
>
> Thanks again for the help. I have run into this problem with several
> models, and I would love to have a nice clean way of running looped
> plots with insets.
...

As I suspected, the problem is you're not keeping axes
consistent--lsline() doesn't let you specify the target axis
(oversight--should have enhancement request filed) and in the order your
code is written the axis w/ focus at the time lsline is executed is the
boxplot so there's no line data for lsline to operate on...

Play around w/ the following revamping of your example and see the
changes I've made--primarily to use axes(h_N_) to change the axes so
following statements apply to the proper set. This is the very thing I
warned you of in the first posting... :)

For text(), legend(), etc., they'll work as documented, again you have
to have the proper axis be the one to which the reference coordinates,
etc., belong to get any joy.

You might also note some changes I made to the data-coding portions to
make it look "more Matlab-y" -- getting rid of the loop at the top and
shortening the logic test at the bottom. If you want make it so you can
eliminate more than the largest outlier at a time, then your SORT()
logic is ok. It again could be done in fewer steps and you don't need
FIND() as shown in the logic test.

HTH...

--

Subject: Looped inset plot

From: dpb

Date: 18 Jan, 2013 22:23:19

Message: 10 of 10

On 1/18/2013 2:55 PM, dpb wrote:
...

> Play around w/ the following revamping of your example and see the
> changes I've made--...

Well, that obviously would be easier if I hadn't forgotten to ^-V... :)

close 1
x = chi2pdf(sort(abs(randn(1,100))),2);
y = x.*abs(randn(size(x)));

figure
h1 = axes;
h2 = axes('pos',[.2 .5 .1 .4]);
set(h2,'fontsize',8)
while true
   axes(h1)
   plot(x,y,'*')
   lsline
   title(['R^2 = ',num2str(corr(x',y')^2,4)])
   axes(h2)
   boxplot(y)

   pause(1)
   m = mean(y);
   outlier = quantile(y,.75) + 1.5*iqr(y);
   if any(y>=outlier)
     [~,ix]=max(y);
     x(ix)=[];
     y(ix)=[];
   else
     break
   end
end

...

Your earlier test code (very slightly modified as well) pasted below...

   z = find(y >= outlier);
   if ~isempty(z)
     [~ ind] = sort(y,'descend');
     y(ind(1)) = [];
     x(ind(1)) = [];
   else
     break
   end

--

Tags for this Thread

What are tags?

A tag is like a keyword or category label associated with each thread. Tags make it easier for you to find threads of interest.

Anyone can tag a thread. Tags are public and visible to everyone.

Contact us