2012-03-23 5 views
72

Я рисую один и тот же тип информации, но для разных стран, с несколькими подзаголовками с matplotlib. То есть, у меня 9 графиков в сетке 3x3, все они одинаковы для строк (разумеется, разные значения для каждой строки).как сделать отдельную легенду для многих подзаговоров с помощью matplotlib?

Однако я не понял, как поставить одну легенду (так как все 9 подзаголовков имеют одинаковые строки) на фигуре только один раз.

Как это сделать?

ответ

68

figlegend может быть то, что вы ищете: http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.figlegend

Пример здесь: http://matplotlib.org/examples/pylab_examples/figlegend_demo.html

Другой пример:

plt.figlegend(lines, labels, loc = 'lower center', ncol=5, labelspacing=0.) 

или:

fig.legend(lines, labels, loc = (0.5, 0), ncol=5) 
+1

Я знаю строки, которые хочу поместить в легенду, но как мне получить переменную 'lines', чтобы вставить аргумент для' legend'? –

+1

@patapouf_ai 'lines' - это список результатов, возвращаемых из' axes.plot() '(т. Е. Каждый' axes.plot' или аналогичная процедура возвращает «строку»). См. Также связанный пример. – Evert

13

Вы просто должны спросите легенду один раз, вне вашей петли.

Например, в этом случае у меня есть 4 подзаголовка с одинаковыми строками и одна легенда.

from matplotlib.pyplot import * 

ficheiros = ['120318.nc', '120319.nc', '120320.nc', '120321.nc'] 

fig = figure() 
fig.suptitle('concentration profile analysis') 

for a in range(len(ficheiros)): 
    # dados is here defined 
    level = dados.variables['level'][:] 

    ax = fig.add_subplot(2,2,a+1) 
    xticks(range(8), ['0h','3h','6h','9h','12h','15h','18h','21h']) 
    ax.set_xlabel('time (hours)') 
    ax.set_ylabel('CONC ($\mu g. m^{-3}$)') 

    for index in range(len(level)): 
     conc = dados.variables['CONC'][4:12,index] * 1e9 
     ax.plot(conc,label=str(level[index])+'m') 

    dados.close() 

ax.legend(bbox_to_anchor=(1.05, 0), loc='lower left', borderaxespad=0.) 
     # it will place the legend on the outer right-hand side of the last axes 

show() 
+3

'figlegend', как было сказано Evert, кажется гораздо лучшим решением;) – carla

+10

проблема' fig.legend() 'заключается в том, что для идентификации всех строк (графиков) требуется идентификация ... как, для каждого подзаголовка , Я использую цикл для генерации строк, единственным решением, которое я решил преодолеть, является создание пустого списка перед вторым циклом, а затем добавление строк по мере их создания ... Затем я использую этот список как аргумент функции 'fig.legend()'. – carla

+0

Аналогичный вопрос [здесь] (https://stackoverflow.com/questions/22001756/one-legend-for-all-subplots-in-pyplot) –

12

Для автоматического позиционирования одной легенды в figure со многими осями, как, полученные с subplots(), следующее решение работает очень хорошо:

plt.legend(lines, labels, loc = 'lower center', bbox_to_anchor = (0,-0.1,1,1), 
      bbox_transform = plt.gcf().transFigure) 

С bbox_to_anchor и bbox_transform=plt.gcf().transFigure вы определяете новый ограничивающий прямоугольник размером figure будет ссылкой для loc. С помощью (0,-0.1,1,1) этот боудинг слегка сдвигается вниз, чтобы легенда не была помещена над другими художниками.

OBS: использовать это решение после использования fig.set_size_inches() и прежде чем использовать fig.tight_layout()

+1

Или simpy 'loc = 'верхний центр', bbox_to_anchor = (0,5, 0), bbox_transform = plt.gcf(). TransFigure', и он не будет перекрываться наверняка. –

+1

Я до сих пор не знаю, почему, но решение Evert не сработало для меня - легенда продолжала прерываться. Это решение (наряду с комментарием Давора) работало очень чисто - легенда была помещена так, как ожидалось, и была полностью видимой. Благодаря! –

7

Существует также хорошая функция get_legend_handles_labels() вы можете вызвать на последней оси (если вы итерацию над ними), что бы собрать все, что вам нужно от label= аргументы:

handles, labels = ax.get_legend_handles_labels() 
fig.legend(handles, labels, loc='upper center') 
+1

Это должен быть главный ответ. – naught101

0

Этот ответ является дополнением к @ Эверт о позиции легенды.

Моя первая попытка решения @ Evert не удалась из-за перекрытий легенды и названия подзаголовка.

Фактически, перекрытия вызваны fig.tight_layout(), что изменяет макет подзаголовков без учета легенды фигуры. Однако необходим fig.tight_layout().

Чтобы избежать перекрытий, мы можем сообщить fig.tight_layout(), чтобы оставить пробелы для легенды фигуры на fig.tight_layout(rect=(0,0,1,0.9)).

Description of tight_layout() parameters.

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