Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
725 views
in Technique[技术] by (71.8m points)

python - Matplotlib ScalarMappable: why need to set_array() if norm set?

I'm trying to plot a set of polygons with a colormap. I set up a ScalarMappable object and generate polygon colors from that ScalarMappable, but when I try to add a colorbar, I get the error:

TypeError: You must first set_array for mappable

The documentation for "set_array" doesn't really say anything, so I'm not at all clear what it is doing, whether I need to give it values, and if I do, what they will be doing.

Can anyone please explain what set_array does, and how I should deal with this?

    plt.clf()
    fig, ax  = plt.subplots(1,1)

    # Set color mappable
    range_min = df.col1.min()
    range_max = df.col1.max()
    cmap = matplotlib.cm.ScalarMappable(
          norm = mcolors.Normalize(range_min, range_max), 
          cmap = plt.get_cmap('binary'))

    for i in polygonDict.keys():
        ax.add_patch(ds.PolygonPatch(polygonDict[i], fc = cmap.to_rgba(df.col1.loc[i])))

    fig.colorbar(cmap, ax = ax)
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

A far easier way to do this is to send an empty array [] to set_array(). I don't really know why, but I've seen it done in this answer, and it works.

The only thing I know is that before you set the array, you get None from get_array(), which is probably why you get this error.

You can do :

plt.clf()
fig, ax  = plt.subplots(1,1)

# Set color mappable
range_min = df.col1.min()
range_max = df.col1.max()
cmap = matplotlib.cm.ScalarMappable(
      norm = mcolors.Normalize(range_min, range_max), 
      cmap = plt.get_cmap('binary'))

for i in polygonDict.keys():
    ax.add_patch(ds.PolygonPatch(polygonDict[i], fc = cmap.to_rgba(df.col1.loc[i])))

cmap.set_array([]) # or alternatively cmap._A = []

fig.colorbar(cmap, ax = ax)

After a few tests, it seems that you can send any array in the world ([df.col1], [0,1], ['hello']) to set_array(), and your colorbar will be the one you want. It just can't be None.

I've noticed that if you set the array to an number array, and then call autoscale(), the min and max values of the colorbar will be the min and max of that array.

I hope this helps.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...