2015-03-02 1 views
1

Я пытаюсь построить набор полигонов с цветовой палитрой. Я создал ScalarMappable объект и создать полигон цвета из этого ScalarMappable, но когда я пытаюсь добавить Colorbar, я получаю ошибку:Matplotlib ScalarMappable: зачем нужно set_array(), если набор норм?

TypeError: You must first set_array for mappable 

Документация «set_array» на самом деле не сказать ничего, так что я «Не совсем понятно, что он делает, нужно ли мне давать ему ценности, и если да, то что они будут делать.

Может кто-нибудь объяснить, что делает set_array, и как мне с этим справиться?

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) 
+1

Это значения, используемые для генерации цветов. 'ScalarMappale' обычно не используется прямо так, как это, но как соединение с другими классами (например,' PolygonCollection'), чтобы вы могли сопоставлять между 'R^1 -> RGBA' – tacaswell

+0

@tcaswell - спасибо. Так что я могу просто передать cmap.set_array() некоторые произвольные значения без забот, так как я уже установил значения vmax и vmin в mcolors.Normalize()? –

+1

Не совсем уверен, как вы это используете, так странно. Я действительно думаю, что вы хотите использовать «PolygonCollection» здесь, так как mpl позаботится обо всем цветовом сопоставлении для вас, я подозреваю, что он будет более результативным по рисованию и проще читать код. – tacaswell

ответ

1

Это может быть слишком поздно, но сегодня я столкнулся с той же проблемой.

Насколько я понимаю, imshow() и scatter() создают отображаемый объект для преобразования из значения с плавающей точкой в ​​цвет в двухэтапном процессе. Сначала число с плавающей запятой сопоставляется с диапазоном 0..1, тогда соответствующий RGB для этого нормализованного номера просматривается в цветовой карте.

Художники, такие как PolygonPatch не создают эту назначаемыми, так что вам нужно сделать это самостоятельно, используя ColorbarBase()

Вот что я в конечном итоге делает.

def createColourbar(lwr, upr): 
    """Create a colourbar with limits of lwr and upr""" 
    cax, kw = matplotlib.colorbar.make_axes(mp.gca()) 
    norm = matplotlib.colors.Normalize(vmin = lwr, vmax = upr, clip = False) 

    c = matplotlib.colorbar.ColorbarBase(cax, cmap=mp.spectral(), norm=norm) 
    return c 
0

Гораздо более простой способ сделать это, чтобы отправить пустой массив [] в set_array(). Я действительно не знаю, почему, но я видел это в this answer, и он работает.

Единственное, что я знаю, это то, что перед установкой массива вы получаете None от get_array(), что, вероятно, является причиной того, почему вы получаете эту ошибку.

Вы можете сделать:

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) 

После нескольких тестов, кажется, что вы можете отправить любой массив в мире ([df.col1], [0,1], [ 'привет']) до set_array(), и ваш цветной барабан будет тем, который вы хотите. Это не может быть None.

Я заметил, что если вы установите массив в массив арбитража, а затем вызовите autoscale(), минимальное и максимальное значения colorbar будут минимальными и максимальными для этого массива.

Надеюсь, это поможет.

Смежные вопросы