2014-12-17 3 views
4

Я использую legend(loc='best') много. Я заметил, что, по-видимому, по умолчанию в верхнем правом углу, если доступно много места. Тем не менее, я хотел бы loc='best' по умолчанию в верхнем левом углу. (Как) можно ли изменить это поведение?matplotlib легенда местоположение по умолчанию

ответ

3

Вы могли бы переопределить метод в Matplotlib, который находит лучшее место,

Это в here.

В @BrenBarn комментариях ниже, и упоминает в своем ответе, волшебство происходит в _get_anchored_bbox, на линии 875.

Добавить это:

from matplotlib.legend import Legend 

def _get_anchored_bbox(self, loc, bbox, parentbbox, renderer): 
    assert loc in range(1, 11) # called only internally 
    BEST, UL, UR, LL, LR, R, CL, CR, LC, UC, C = list(xrange(11)) 
    anchor_coefs = {UR: "NE", UL: "NW", LL: "SW", LR: "SE", R: "E", 
        CL: "W", CR: "E", LC: "S", UC: "N", C: "C"} 

    c = anchor_coefs[loc] 

    fontsize = renderer.points_to_pixels(self._fontsize) 
    container = parentbbox.padded(-(self.borderaxespad) * fontsize) 
    anchored_box = bbox.anchored(c, container=container) 
    return anchored_box.x0, anchored_box.y0   

Legend._get_anchored_bbox = _get_anchored_bbox 

В верхней части кода, и он изменяет поведение. Я удалил комментарии и немного изменил интервал, чтобы уменьшить занятость. В качестве альтернативы вы можете просто выгрузить его в другой файл, назовите его legendLocationHack.py и вызовите его, когда захотите.

+0

Ах, если это работает, это гениальное исправление/взлом: D – Ffisegydd

+0

Я не думаю, что это гарантированно сработает, поскольку «коды» - это dict, а dicts не имеют надежного порядка. Фактическое упорядочение происходит в '_get_anchored_bbox' (см. Мой ответ). Конечно, любой вид подобной подобной игры может сломаться с более поздними версиями, поэтому, если это работает, это проще, чем мое решение. – BrenBarn

3

Вы можете отправить обезьяну matplotlib.legend.Legend._get_anchored_bbox. Эта функция содержит этот код:

BEST, UR, UL, LL, LR, R, CL, CR, LC, UC, C = list(xrange(11)) 

anchor_coefs = {UR: "NE", 
       UL: "NW", 
       LL: "SW", 
       LR: "SE", 
       R: "E", 
       CL: "W", 
       CR: "E", 
       LC: "S", 
       UC: "N", 
       C: "C"} 

Это отображает последовательные «коды положения» в пространственные местоположения. Код вычисления ошибки в _find_best_position нарушает связь плохой ситуации, беря самое раннее положение в последовательности, поэтому верхняя правая победит, если другая позиция на самом деле лучше. Я думаю, что вы можете спокойно поменять коды, написав новую версию функции меняющейся первую строку:

BEST, UL, UR, LL, LR, R, CL, CR, LC, UC, C = list(xrange(11)) 

Обратите внимание, что я переключился UL и UR. Когда я пробую это на простом V-образном графике, он помещает легенду в верхнем правом углу перед изменением, но в верхнем левом углу после изменения.

Чтобы внести изменения в monkeypatch, вы должны переопределить свою собственную версию _get_anchored_bbox, а затем сделать matplotlib.legend.Legend._get_anchored_bbox = my_get_anchored_bbox.

Любой такой раствор обезьяны должен рассматриваться как хрупкий. Это может сломаться, если что-то изменится в более поздней версии matplotlib, так как оно включает в себя переопределение внутренних функций, с которыми вам не нужно общаться. Возможно, лучше спросить в списке рассылки matplotlib или поднять проблему в трекере ошибок, запросив настраиваемый параметр, чтобы установить порядок установления связи.

+0

Было бы довольно легко подтолкнуть изменения, которые позволят вам поместить * по умолчанию * упорядочение местоположений ради одинаково взвешенных мест ... – will

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