Home > Enterprise >  how to distinguish axes between image, line plot and colorbar?
how to distinguish axes between image, line plot and colorbar?

Time:11-24

I am trying to make a generic function which can arrange multiple figures as subplots. I need to loop over the subplots to adjust and uniform some properties (e.g. axis range), and I am doing it by iterating over fig.axes.

I am having some trouble in handling the different kinds of plots (which can be mixed in my application) e.g. I may want to set same x range for image and for line plot, but I don't want to do it for colorbar, so: what is the best way of distinguish the different kind of plots (and in case other kinds if they will arise, e.g. as subclasses)?

At the moment the best way I found is to play with try and except and select on the basis of different properties e.g. if len(ax.images) > 0 it is an image plot, but I cannot find a difference between line and colorbars (both don't have images), and in any case, what is the best way?

I tried to compare them with the following code, which creates three axes l, i and cb (respectively line, image, colorbar):

# create test figure
plt.figure()
b = np.arange(12).reshape([4,3])
plt.subplot(121)
plt.plot([1,2,3],[4,5,6])
plt.subplot(122)
plt.imshow(b)
plt.colorbar()

# create  test objects
ax=plt.gca()
fig=plt.gcf()
l,i,cb = fig.axes

# do a simple test, images are different:
for o in l,i,cb: print(len(o.images))

# this also doesn't work in finding properties not in common between lines and colobars, gives empty list.
[a for a in dir(l) if a not in dir(cb)]

CodePudding user response:

I have to remind you that

  1. Matplotib provides you with many different container objects,
  2. You can store the Axes destination in a list, or a dictionary, when you use it — you can even say ax.ax_type = 'lineplot'.

That said, e.g.,

from matplotlib.pyplot import subplots, plot
fig, ax = subplots()
plot((1, 2), (2, 1))
...
axes_types = []
for ax_i in fig.axes:
    try:
        ax_i.__getattr__('get_clabel')
        axes_types.append('colorbar')
    except AttributeError:
        axes_types.append('lineplot')
...

In other word, chose a method that is unique to each one of the differnt types you're testing and check if it's available.

CodePudding user response:

Matplotlib commands you have used in the first few lines of your code return values, either the axes or the objects that know their axes. Below is an example of how you can use the returned values to extract the axes info.

import matplotlib.pyplot as plt
import numpy as np 

fig = plt.figure()
ax1 = plt.subplot(121)
ax1.plot([1,2,3],[4,5,6])
ax2 = plt.subplot(122)
plt.imshow(np.arange(12).reshape([4,3]))
cbar = plt.colorbar()
ax3 = cbar.ax

# create  test objects
ax=plt.gca()
fig=plt.gcf()
l,i,cb = fig.axes

print('original method')
for o in l,i,cb: print(len(o.images), o)
print('suggested method')
for o in (ax1, ax2, ax3): print(len(o.images), o)
 
# this also doesn't work in finding properties not in common between lines and colobars, gives empty list.
[a for a in dir(l) if a not in dir(cb)]

plt.show()

I have printed out axes objects obtained using my method, the output is the same as using your method.

0 AxesSubplot(0.125,0.11;0.352273x0.77)
1 AxesSubplot(0.547727,0.11;0.281818x0.77)
0 AxesSubplot(0.847159,0.11;0.0528409x0.77)
suggested method
0 AxesSubplot(0.125,0.11;0.352273x0.77)
1 AxesSubplot(0.547727,0.11;0.281818x0.77)
0 AxesSubplot(0.847159,0.11;0.0528409x0.77)
  • Related