Path: csiph.com!v102.xanadu-bbs.net!xanadu-bbs.net!feeder.erje.net!eu.feeder.erje.net!newsfeed.xs4all.nl!newsfeed4a.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.001 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; '16,': 0.03; 'skip:[ 20': 0.04; 'explicitly': 0.05; '*not*': 0.07; 'lines,': 0.07; 'memory.': 0.07; 'attributes': 0.09; 'curve': 0.09; 'indicates': 0.09; 'lines:': 0.09; 'matplotlib': 0.09; 'subject:plot': 0.09; 'window.': 0.09; 'subject:question': 0.10; 'api': 0.11; 'cc:addr :python-list': 0.11; 'creates': 0.14; '"default"': 0.16; '(note,': 0.16; '36,': 0.16; '49,': 0.16; '64,': 0.16; 'ast': 0.16; 'bars': 0.16; 'caching': 0.16; 'called.': 0.16; 'cc:name:python list': 0.16; 'command,': 0.16; 'interpreter,': 0.16; 'namespace.': 0.16; 'numpy': 0.16; 'rarely': 0.16; 'applies': 0.16; 'demonstrate': 0.16; 'prevent': 0.16; 'wrote:': 0.18; "python's": 0.19; 'thu,': 0.19; '8bit%:5': 0.22; 'feb': 0.22; '>>>': 0.22; 'import': 0.22; 'cc:addr:python.org': 0.22; 'error': 0.23; '>>>': 0.24; '(by': 0.24; 'instance,': 0.24; 'skip:i 40': 0.24; 'specify': 0.24; 'question': 0.24; 'cc:2**0': 0.24; 'source': 0.25; 'references': 0.26; 'skip:" 20': 0.27; 'header:In-Reply-To:1': 0.27; 'function': 0.29; '[1]': 0.29; 'am,': 0.29; 'properties': 0.29; "doesn't": 0.30; '(like': 0.30; 'message- id:@mail.gmail.com': 0.30; 'lines': 0.31; '25,': 0.31; '>>>>': 0.31; 'stands': 0.31; 'quite': 0.32; 'skip:& 30': 0.33; 'comment': 0.34; 'skip:d 20': 0.34; 'subject:from': 0.34; 'common': 0.35; 'objects': 0.35; 'but': 0.35; 'received:google.com': 0.35; 'there': 0.35; '8bit%:17': 0.36; 'done': 0.36; 'method': 0.36; 'should': 0.36; 'list': 0.37; 'being': 0.38; 'skip:o 20': 0.38; 'skip:& 10': 0.38; 'jason': 0.38; 'whatever': 0.38; 'rather': 0.38; 'that,': 0.38; 'skip:& 20': 0.39; 'does': 0.39; 'skip:8 10': 0.39; 'either': 0.39; 'university': 0.39; 'skip:x 10': 0.40; 'how': 0.40; 'even': 0.60; 'most': 0.60; 'hope': 0.61; 'color': 0.61; 'skip:a 30': 0.61; 'skip:a 50': 0.61; 'save': 0.62; 'personal': 0.63; 'such': 0.63; 'skip:n 10': 0.64; '8bit%:10': 0.64; 'places': 0.64; 'more': 0.64; 'skip:\xe2 10': 0.65; 'it!': 0.67; 'online': 0.71; '2015': 0.84; '8bit%:16': 0.84; 'coupled': 0.84; 'draws': 0.84; 'hats': 0.84; 'popular.': 0.84; 'skip:\xe2 30': 0.91; 'to:none': 0.92; '8bit%:18': 0.93; 'success!': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=fJvcai9DOzUMyPK7fpJYhL1lns0g/btlVOAPIdFsqhE=; b=oWiIfGAqUZmha6DNfh7jz2bIi/3ncRBxwafD9DU0Da3BDT2rNU7Nxu5LKNfzb88xYc 382AdKhmCixCA+YFQRBrOjErq+J87xrmxUhgljJIKtDvsypPuxW/IWjnXlBRvhZ9HBbM RmT4EeHirnBUJuwSbuEtl2DmqIrA+FUq7ULLUIsDbhIcv7Tz91RTrcc3tlTWKAi1zvsk qTFDo7BaWsY4FoGh0guPB+kfgACbeDDU97cgUC8CdAK1QtT+sXju0VKmeXIWMzxNZRQl PKOUaSvdjeEIgvE7xgGa09kKQHNMsTWMIrVj2BoSalQSFzIKqjQtd0pG1hUti+QY7u9l uZSg== MIME-Version: 1.0 X-Received: by 10.236.96.232 with SMTP id r68mr4531138yhf.73.1424379919075; Thu, 19 Feb 2015 13:05:19 -0800 (PST) In-Reply-To: <54e5bf49$0$3054$426a74cc@news.free.fr> References: <54e5bf49$0$3054$426a74cc@news.free.fr> Date: Thu, 19 Feb 2015 16:05:19 -0500 Subject: Re: A question about how plot from matplotlib works From: Jason Swails Cc: python list Content-Type: multipart/alternative; boundary=001a11c1b9d01a0f40050f774b0f X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 264 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1424379921 news.xs4all.nl 2857 [2001:888:2000:d::a6]:53582 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:85935 --001a11c1b9d01a0f40050f774b0f Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable On Thu, Feb 19, 2015 at 5:47 AM, ast wrote: > Hello > > import numpy as np >>>> import matplotlib.pyplot as plt >>>> x =3D np.arange(10) >>>> y =3D x**2 >>>> x >>>> >>> array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) > >> y >>>> >>> array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81]) > >> plt.plot(x,y) >>>> >>> [] > >> plt.show() >>>> >>> > > The question is: > > plt.plot() creates an object "matplotlib.lines.Line2D" but this object is > not referenced. So this object should disapear from memory. But > this doesn't happens since plt.show() draws the curve on a graphic > window. So how does it work ? =E2=80=8BA reference to it is put in the "active" Axes instance of the matplotlib.pyplot namespace. There are many things that will prevent an object from being garbage-collected (a common source of references are caches). [1] =E2=80=8BIn general, matplotlib has many containers. In particular, Line2D= objects generated by the "plot" function are added to the Axes instance from which "plot" was called. When you don't explicitly specify an Axes object from which to plot, matplotlib.pyplot applies it to some "default" Axes instance living in the matplotlib.pyplot namespace.=E2=80=8B This is done to give matplotlib more of a Matlab-like feel. To demonstrate this, let's go try and FIND that reference to the lines: >>> import matplotlib.pyplot as plt =E2=80=8B>>> import numpy as np =E2=80=8B>>> x =3D np.arange(10) =E2=80=8B>>> y =3D x ** 2 =E2=80=8B>>> x =E2=80=8Barray([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) =E2=80=8B>>> y =E2=80=8Barray([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81]) =E2=80=8B>>> lines, =3D plt.plot(x, y) =E2=80=8B>>> id(lines) =E2=80=8B4466622800 =E2=80=8B=E2=80=8B >>> lines =E2=80=8B =E2=80=8B>>> del lines =E2=80=8B>>> # Now let's find those lines =E2=80=8B... active_axes =3D plt.gca() # Get Current Axes =E2=80=8B>>> dir(active_axes) =E2=80=8B[..., get_lines, ...] <-- this is snipped for brevity =E2=80=8B>>> active_axes.get_lines() =E2=80=8B =E2=80=8B>>> active_axes.get_lines()[0] =E2=80=8B =E2=80=8B>>> id(active_axes.get_lines()[0]) =E2=80=8B4466622800 And there we have it! Success! (Note, my comment indicates that the gca in plt.gca() stands for "Get Current Axes"). I also snipped the list of attributes in active_axes that I got from the "dir" command, since that list is HUGE, but the method we want is, rather expectedly, "get_lines". In *my* personal opinion, the matplotlib API is quite intuitive, such that, coupled with Python's native introspective functions (like dir() and id()) and "help" function in the interpreter, I rarely have to consult StackOverflow or even the API documentation online to do what I need. For instance, you want to change the color or thickness of the error bar hats on error bars in your plot? Either save a reference to them when they are generated (by plt.errorbar, for instance), or go *find* them inside the Axes you are manipulating and set whatever properties you want. Hope this helps, Jason [1] OK, so there are not many *things* -- only if there are active, non-circular references will the object *not* be garbage-collected, loosely speaking. But there are many reasons and places that such references are generated inside many APIs... caching being one of the most popular. --=20 Jason M. Swails BioMaPS, Rutgers University Postdoctoral Researcher --001a11c1b9d01a0f40050f774b0f Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable

On Thu, F= eb 19, 2015 at 5:47 AM, ast <nomail@invalid.com> wrote:
=
Hello

import numpy as np
import matplotlib.pyplot as plt
x =3D np.arange(10)
y =3D x**2
x
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
y
array([ 0,=C2=A0 1,=C2=A0 4,=C2=A0 9, 16, 25, 36, 49, 64, 81])
plt.plot(x,y)
[<matplotlib.lines.Line2D object at 0x044F5930>]
plt.show()


The question is:

plt.plot() creates an object "matplotlib.lines.Line2D" but this o= bject is
not referenced. So this object should disapear from memory. But
this doesn't happens since plt.show() draws the curve on a graphic
window. So how does it work ?

=E2=80=8BA refere= nce to it is put in the "active" Axes instance of the matplotlib.= pyplot namespace.=C2=A0 There are many things that will prevent an object f= rom being garbage-collected (a common source of references are caches). [1]=

=E2=80=8BIn general, matplotlib has many containers.=C2=A0 I= n particular, Line2D objects generated by the "plot" function are= added to the Axes instance from which "plot" was called.=C2=A0 W= hen you don't explicitly specify an Axes object from which to plot, mat= plotlib.pyplot applies it to some "default" Axes instance living = in the matplotlib.pyplot namespace.=E2=80=8B

This is done to give matplotlib more of a Matlab-like= feel.=C2=A0 To demonstrate this, let's go try and FIND that reference = to the lines:
=
>>> import matplotlib.pyplot as plt
=E2=80=8B>>> import numpy as np
=E2=80=8B>>> x =3D np.arange(10)
=E2=80=8B= >>> y =3D x ** 2
=E2=80=8B>>>= ; x
=E2= =80=8Barray([0, 1, 2, 3, 4, 5, 6, 7, 8,= 9])
= =E2=80=8B>>> y
=E2=80=8Barray([ 0, =C2=A01, =C2=A04, =C2=A09, 16, 25, 36, = 49, 64, 81])
=E2=80=8B>>> lines, =3D = plt.plot(x, y)
=E2=80=8B>>> id(lines)=
=E2=80= =8B4466622800
=E2=80=8B=E2=80=8B
>>> lines
=E2=80=8B<mat= plotlib.lines.Line2D object at 0x10a3b4150>
=E2=80=8B>>> del lines
=E2=80=8B>= >> # Now let's find those lines
=E2=80=8B... active_axes =3D plt.gca() # Get Current Axes
=E2=80=8B>>> dir(active_axes)
=E2=80=8B[..., get_lines, ...] <-- this is snipped for brevity
=E2=80=8B>>> active_axes.get_lines()
=E2=80=8B<a list of 1 Line2D objects>
=E2=80=8B>>> active_axes.get_lines()[0]<= /div>
=E2=80=8B<matplotlib.lines.Line2D object at 0x10a3= b4150>
=E2=80=8B>>> id(active_axes= .get_lines()[0])
=E2=80=8B4466622800

And there we ha= ve it!=C2=A0 Success! =C2=A0(Note, my comment indicates that the gca in plt= .gca() stands for "Get Current Axes").=C2=A0 I also snipped the l= ist of attributes in active_axes that I got from the "dir" comman= d, since that list is HUGE, but the method we want is, rather expectedly, &= quot;get_lines".

In *my* personal opinion, the matplotlib API is quite= intuitive, such that, coupled with Python's native introspective funct= ions (like dir() and id()) and "help" function in the interpreter= , I rarely have to consult StackOverflow or even the API documentation onli= ne to do what I need.

For instance, you want to change the color or thickness= of the error bar hats on error bars in your plot?=C2=A0 Either save a refe= rence to them when they are generated (by plt.errorbar, for instance), or g= o *find* them inside the Axes you are manipulating and set whatever propert= ies you want.

Hope this helps,
Jason
<= div class=3D"gmail_default">
[1] OK, = so there are not many *things* -- only if there are active, non-circular re= ferences will the object *not* be garbage-collected, loosely speaking.=C2= =A0 But there are many reasons and places that such references are generate= d inside many APIs... caching being one of the most popular.

--
<= div dir=3D"ltr">Jason M. Swails
BioMaPS,
Rutgers University
Postdo= ctoral Researcher
--001a11c1b9d01a0f40050f774b0f--