Axes array for subplots

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Axes array for subplots

Virgil Stokes
The following line is part of a much larger python (3.6) with Matplotlib (2.2.2) program in which the number of subplots is determined from input data:

  fig, axarr = plt.subplots(NSub, figsize=(width,height), sharex=True)

This works fine when the number of subplots (NSub) is greater than 1. For example when NSub=3, axarr is an array of length 3 and contains:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x0000025900E9DDD8>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011897F0>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011C7128>],
        dtype=object)

However, when NSub=1, axarr contains:

  <matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>

and of course, will give an error if axarr is an array; i.e.

 
builtins.TypeError: 'AxesSubplot' object does not support indexing

For my code this requires special handling because axarr is no longer an array. Why not have axarr contain:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>],dtype=object)

when NSub=1. IMHO this is consistent; i.e. it is an array with a length that is equal to the number of subplots.
_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Axes array for subplots

Benjamin Root
By default, `squeeze` is called on the array prior to returning it. This way, users don't need to deal with 2D arrays when most of the time, they are dealing with 1D setups. You can specify squeeze=False to subplots to turn this behavior off and always have a 2D array.

I hope that helps!
Ben Root


On Tue, Apr 17, 2018 at 10:12 AM, Virgil Stokes <[hidden email]> wrote:
The following line is part of a much larger python (3.6) with Matplotlib (2.2.2) program in which the number of subplots is determined from input data:

  fig, axarr = plt.subplots(NSub, figsize=(width,height), sharex=True)

This works fine when the number of subplots (NSub) is greater than 1. For example when NSub=3, axarr is an array of length 3 and contains:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x0000025900E9DDD8>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011897F0>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011C7128>],
        dtype=object)

However, when NSub=1, axarr contains:

  <matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>

and of course, will give an error if axarr is an array; i.e.

 
builtins.TypeError: 'AxesSubplot' object does not support indexing

For my code this requires special handling because axarr is no longer an array. Why not have axarr contain:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>],dtype=object)

when NSub=1. IMHO this is consistent; i.e. it is an array with a length that is equal to the number of subplots.

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users



_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Axes array for subplots

Virgil Stokes

Ok Ben,

I tried the following per your suggestion:

  fig, axarr = plt.subplots(NSub, figsize=(width,height), squeeze=False, sharex=True)

but when the following is executed:

  ax.grid(True)

I get the following error message: 
  builtins.AttributeError: 'numpy.ndarray' object has no attribute 'grid'

But, thanks for your help :-).


On 2018-04-17 16:30, Benjamin Root wrote:
By default, `squeeze` is called on the array prior to returning it. This way, users don't need to deal with 2D arrays when most of the time, they are dealing with 1D setups. You can specify squeeze=False to subplots to turn this behavior off and always have a 2D array.

I hope that helps!
Ben Root


On Tue, Apr 17, 2018 at 10:12 AM, Virgil Stokes <[hidden email]> wrote:
The following line is part of a much larger python (3.6) with Matplotlib (2.2.2) program in which the number of subplots is determined from input data:

  fig, axarr = plt.subplots(NSub, figsize=(width,height), sharex=True)

This works fine when the number of subplots (NSub) is greater than 1. For example when NSub=3, axarr is an array of length 3 and contains:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x0000025900E9DDD8>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011897F0>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011C7128>],
        dtype=object)

However, when NSub=1, axarr contains:

  <matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>

and of course, will give an error if axarr is an array; i.e.

 
builtins.TypeError: 'AxesSubplot' object does not support indexing

For my code this requires special handling because axarr is no longer an array. Why not have axarr contain:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>],dtype=object)

when NSub=1. IMHO this is consistent; i.e. it is an array with a length that is equal to the number of subplots.

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users




_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Axes array for subplots

Benjamin Root
Virgil,

How did you get from `axarr` to `ax`? The error message suggests that you haven't fully indexed the result. Remember, with squeeze=False, `axarr` will be a 2-D array, requiring two indices.

Ben

On Tue, Apr 17, 2018 at 11:14 AM, Virgil Stokes <[hidden email]> wrote:

Ok Ben,

I tried the following per your suggestion:

  fig, axarr = plt.subplots(NSub, figsize=(width,height), squeeze=False, sharex=True)

but when the following is executed:

  ax.grid(True)

I get the following error message: 
  builtins.AttributeError: 'numpy.ndarray' object has no attribute 'grid'

But, thanks for your help :-).


On 2018-04-17 16:30, Benjamin Root wrote:
By default, `squeeze` is called on the array prior to returning it. This way, users don't need to deal with 2D arrays when most of the time, they are dealing with 1D setups. You can specify squeeze=False to subplots to turn this behavior off and always have a 2D array.

I hope that helps!
Ben Root


On Tue, Apr 17, 2018 at 10:12 AM, Virgil Stokes <[hidden email]> wrote:
The following line is part of a much larger python (3.6) with Matplotlib (2.2.2) program in which the number of subplots is determined from input data:

  fig, axarr = plt.subplots(NSub, figsize=(width,height), sharex=True)

This works fine when the number of subplots (NSub) is greater than 1. For example when NSub=3, axarr is an array of length 3 and contains:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x0000025900E9DDD8>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011897F0>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011C7128>],
        dtype=object)

However, when NSub=1, axarr contains:

  <matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>

and of course, will give an error if axarr is an array; i.e.

 
builtins.TypeError: 'AxesSubplot' object does not support indexing

For my code this requires special handling because axarr is no longer an array. Why not have axarr contain:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>],dtype=object)

when NSub=1. IMHO this is consistent; i.e. it is an array with a length that is equal to the number of subplots.

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users





_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Axes array for subplots

Slavin, Jonathan
In reply to this post by Virgil Stokes
​Virgil,

What is ax in your example?  When I do
fig,axarr = plt.subplots(1,squeeze=False,sharex=True)
I get axarr is an array of shape (1,1).  An array does not have an attribute grid.

Jon
 

Date: Tue, 17 Apr 2018 17:14:28 +0200
From: Virgil Stokes <[hidden email]>
To: Benjamin Root <[hidden email]>,
        <[hidden email]>
Subject: Re: [Matplotlib-users] Axes array for subplots
Message-ID: <[hidden email]>
Content-Type: text/plain; charset="utf-8"; Format="flowed"

Ok Ben,

I tried the following per your suggestion:

fig, axarr = plt.subplots(NSub, figsize=(width,height), squeeze=False,
sharex=True)

but when the following is executed:

 ? ax.grid(True)

I get the following error message:
 ? builtins.AttributeError: 'numpy.ndarray' object has no attribute 'grid'

But, thanks for your help :-).


On 2018-04-17 16:30, Benjamin Root wrote:
> By default, `squeeze` is called on the array prior to returning it.
> This way, users don't need to deal with 2D arrays when most of the
> time, they are dealing with 1D setups. You can specify squeeze=False
> to subplots to turn this behavior off and always have a 2D array.
>
> I hope that helps!
> Ben Root
>
>
> On Tue, Apr 17, 2018 at 10:12 AM, Virgil Stokes <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     The following line is part of a much larger python (3.6) with
>     Matplotlib (2.2.2) program in which the number of subplots is
>     determined from input data:
>
>     fig, axarr = plt.subplots(NSub, figsize=(width,height), sharex=True)
>
>     This works fine when the number of subplots (NSub) is greater than
>     1. For example when NSub=3, axarr is an array of length 3 and
>     contains:
>
>     array([<matplotlib.axes._subplots.AxesSubplot object at
>     0x0000025900E9DDD8>,
>     ???????? <matplotlib.axes._subplots.AxesSubplot object at
>     0x00000259011897F0>,
>     ???????? <matplotlib.axes._subplots.AxesSubplot object at
>     0x00000259011C7128>],
>     ??????? dtype=object)
>
>     However, when NSub=1, axarr contains:
>
>     <matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>
>
>     and of course, will give an error if axarr is an array; i.e.
>
>     builtins.TypeError: 'AxesSubplot' object does not support indexing
>
>     For my code this requires special handling because axarr is no
>     longer an array. Why not have axarr contain:
>
>     array([<matplotlib.axes._subplots.AxesSubplot object at
>     0x00000161AB26AE80>],dtype=object)
>
>     when NSub=1. IMHO this is consistent; i.e. it is an array with a
>     length that is equal to the number of subplots.
>
>     _______________________________________________
>     Matplotlib-users mailing list
>     [hidden email] <mailto:[hidden email]>
>     https://mail.python.org/mailman/listinfo/matplotlib-users
>     <https://mail.python.org/mailman/listinfo/matplotlib-users>
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20180417/ced451e1/attachment.html>

------------------------------

Subject: Digest Footer

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users


------------------------------

End of Matplotlib-users Digest, Vol 33, Issue 10
************************************************



--
________________________________________________________
Jonathan D. Slavin                 Harvard-Smithsonian CfA
[hidden email]       60 Garden Street, MS 83
phone: (617) 496-7981       Cambridge, MA 02138-1516
cell: (781) 363-0035             USA
________________________________________________________


_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Axes array for subplots

Virgil Stokes
In reply to this post by Benjamin Root

ax is used in a function that references axarr. My problem is not about 2D arrays.

--V


On 2018-04-17 17:22, Benjamin Root wrote:
Virgil,

How did you get from `axarr` to `ax`? The error message suggests that you haven't fully indexed the result. Remember, with squeeze=False, `axarr` will be a 2-D array, requiring two indices.

Ben

On Tue, Apr 17, 2018 at 11:14 AM, Virgil Stokes <[hidden email]> wrote:

Ok Ben,

I tried the following per your suggestion:

  fig, axarr = plt.subplots(NSub, figsize=(width,height), squeeze=False, sharex=True)

but when the following is executed:

  ax.grid(True)

I get the following error message: 
  builtins.AttributeError: 'numpy.ndarray' object has no attribute 'grid'

But, thanks for your help :-).


On 2018-04-17 16:30, Benjamin Root wrote:
By default, `squeeze` is called on the array prior to returning it. This way, users don't need to deal with 2D arrays when most of the time, they are dealing with 1D setups. You can specify squeeze=False to subplots to turn this behavior off and always have a 2D array.

I hope that helps!
Ben Root


On Tue, Apr 17, 2018 at 10:12 AM, Virgil Stokes <[hidden email]> wrote:
The following line is part of a much larger python (3.6) with Matplotlib (2.2.2) program in which the number of subplots is determined from input data:

  fig, axarr = plt.subplots(NSub, figsize=(width,height), sharex=True)

This works fine when the number of subplots (NSub) is greater than 1. For example when NSub=3, axarr is an array of length 3 and contains:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x0000025900E9DDD8>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011897F0>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011C7128>],
        dtype=object)

However, when NSub=1, axarr contains:

  <matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>

and of course, will give an error if axarr is an array; i.e.

 
builtins.TypeError: 'AxesSubplot' object does not support indexing

For my code this requires special handling because axarr is no longer an array. Why not have axarr contain:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>],dtype=object)

when NSub=1. IMHO this is consistent; i.e. it is an array with a length that is equal to the number of subplots.

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users






_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Axes array for subplots

Benjamin Root
Virgil, I will be very specific: The following all references the copy of Plotting_Test03.py you sent me.

At line 263, you have a comment: "# The Axes array (axarr) will be a list of NSub objects  (an axis for each subplot)". This is incorrect. `axarr` is not a list, but a numpy array *or scalar*. When plt.subplots(1) is called, you get a numpy scalar, which is the problem that you originally approached us about. When plt.subplots(2) is called, you get a 1D numpy array, which looks a lot like a list.

However, if plt.subplots(2, squeeze=False) is called, then you get a *2D* numpy array of axes, of shape (2, 1). That is because plt.subplots(), in the general case, is used for specifying the number of rows and columns of subplots, so without squeezing, the axes array is 2D.

Therefore, if you have squeeze=False turned on in plt.subplots(), then line 306 needs to change to `ax = axarr[j, 0]`. Similar to line 318, and the area around line 331.

Ben Root



On Tue, Apr 17, 2018 at 2:26 PM, Virgil Stokes <[hidden email]> wrote:

ax is used in a function that references axarr. My problem is not about 2D arrays.

--V


On 2018-04-17 17:22, Benjamin Root wrote:
Virgil,

How did you get from `axarr` to `ax`? The error message suggests that you haven't fully indexed the result. Remember, with squeeze=False, `axarr` will be a 2-D array, requiring two indices.

Ben

On Tue, Apr 17, 2018 at 11:14 AM, Virgil Stokes <[hidden email]> wrote:

Ok Ben,

I tried the following per your suggestion:

  fig, axarr = plt.subplots(NSub, figsize=(width,height), squeeze=False, sharex=True)

but when the following is executed:

  ax.grid(True)

I get the following error message: 
  builtins.AttributeError: 'numpy.ndarray' object has no attribute 'grid'

But, thanks for your help :-).


On 2018-04-17 16:30, Benjamin Root wrote:
By default, `squeeze` is called on the array prior to returning it. This way, users don't need to deal with 2D arrays when most of the time, they are dealing with 1D setups. You can specify squeeze=False to subplots to turn this behavior off and always have a 2D array.

I hope that helps!
Ben Root


On Tue, Apr 17, 2018 at 10:12 AM, Virgil Stokes <[hidden email]> wrote:
The following line is part of a much larger python (3.6) with Matplotlib (2.2.2) program in which the number of subplots is determined from input data:

  fig, axarr = plt.subplots(NSub, figsize=(width,height), sharex=True)

This works fine when the number of subplots (NSub) is greater than 1. For example when NSub=3, axarr is an array of length 3 and contains:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x0000025900E9DDD8>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011897F0>,
         <matplotlib.axes._subplots.AxesSubplot object at 0x00000259011C7128>],
        dtype=object)

However, when NSub=1, axarr contains:

  <matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>

and of course, will give an error if axarr is an array; i.e.

 
builtins.TypeError: 'AxesSubplot' object does not support indexing

For my code this requires special handling because axarr is no longer an array. Why not have axarr contain:

  array([<matplotlib.axes._subplots.AxesSubplot object at 0x00000161AB26AE80>],dtype=object)

when NSub=1. IMHO this is consistent; i.e. it is an array with a length that is equal to the number of subplots.

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users







_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users
Reply | Threaded
Open this post in threaded view
|

Re: Axes array for subplots

vincent.adrien@gmail.com
In reply to this post by Virgil Stokes
Hi Virgil,

I suspect that should you are using something like
```
ax = axarr[i]
```
while `squeeze=False` will require that you use
```
ax = axarr[i, 0]
```
(from what I understood from you example).

Please find attached a code snippet that should hopefully better
demonstrate this.

Best regards,
Adrien

On 04/17/2018 11:26 AM, Virgil Stokes wrote:

> ax is used in a function that references axarr. My problem is not about
> 2D arrays.
>
> --V
>
>
> On 2018-04-17 17:22, Benjamin Root wrote:
>> Virgil,
>>
>> How did you get from `axarr` to `ax`? The error message suggests that
>> you haven't fully indexed the result. Remember, with squeeze=False,
>> `axarr` will be a 2-D array, requiring two indices.
>>
>> Ben
>>
>> On Tue, Apr 17, 2018 at 11:14 AM, Virgil Stokes <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>>     Ok Ben,
>>
>>     I tried the following per your suggestion:
>>
>>     fig, axarr = plt.subplots(NSub, figsize=(width,height),
>>     squeeze=False, sharex=True)
>>
>>     but when the following is executed:
>>
>>       ax.grid(True)
>>
>>     I get the following error message:
>>     builtins.AttributeError: 'numpy.ndarray' object has no attribute
>>     'grid'
>>
>>     But, thanks for your help :-).
>>
>>
>>     On 2018-04-17 16:30, Benjamin Root wrote:
>>>     By default, `squeeze` is called on the array prior to returning
>>>     it. This way, users don't need to deal with 2D arrays when most
>>>     of the time, they are dealing with 1D setups. You can specify
>>>     squeeze=False to subplots to turn this behavior off and always
>>>     have a 2D array.
>>>
>>>     I hope that helps!
>>>     Ben Root
>>>
>>>
>>>     On Tue, Apr 17, 2018 at 10:12 AM, Virgil Stokes <[hidden email]
>>>     <mailto:[hidden email]>> wrote:
>>>
>>>         The following line is part of a much larger python (3.6) with
>>>         Matplotlib (2.2.2) program in which the number of subplots is
>>>         determined from input data:
>>>
>>>         fig, axarr = plt.subplots(NSub, figsize=(width,height),
>>>         sharex=True)
>>>
>>>         This works fine when the number of subplots (NSub) is greater
>>>         than 1. For example when NSub=3, axarr is an array of length
>>>         3 and contains:
>>>
>>>         array([<matplotlib.axes._subplots.AxesSubplot object at
>>>         0x0000025900E9DDD8>,
>>>         <matplotlib.axes._subplots.AxesSubplot object at
>>>         0x00000259011897F0>,
>>>         <matplotlib.axes._subplots.AxesSubplot object at
>>>         0x00000259011C7128>],
>>>                 dtype=object)
>>>
>>>         However, when NSub=1, axarr contains:
>>>
>>>         <matplotlib.axes._subplots.AxesSubplot object at
>>>         0x00000161AB26AE80>
>>>
>>>         and of course, will give an error if axarr is an array; i.e.
>>>
>>>         builtins.TypeError: 'AxesSubplot' object does not support
>>>         indexing
>>>
>>>         For my code this requires special handling because axarr is
>>>         no longer an array. Why not have axarr contain:
>>>
>>>         array([<matplotlib.axes._subplots.AxesSubplot object at
>>>         0x00000161AB26AE80>],dtype=object)
>>>
>>>         when NSub=1. IMHO this is consistent; i.e. it is an array
>>>         with a length that is equal to the number of subplots.
>>>
>>>         _______________________________________________
>>>         Matplotlib-users mailing list
>>>         [hidden email] <mailto:[hidden email]>
>>>         https://mail.python.org/mailman/listinfo/matplotlib-users
>>>         <https://mail.python.org/mailman/listinfo/matplotlib-users>
>>>
>>>
>>
>>
>
>
>
> _______________________________________________
> Matplotlib-users mailing list
> [hidden email]
> https://mail.python.org/mailman/listinfo/matplotlib-users
>

_______________________________________________
Matplotlib-users mailing list
[hidden email]
https://mail.python.org/mailman/listinfo/matplotlib-users

example_virgil.py (898 bytes) Download Attachment