ROOT 가이드

5.1 범례 클래스 TLegend

TLegend 클래스는 캔버스안에 그린 여러 히스토그램, 그래프, 함수 등을 설명하는 범례를 그릴 때 사용한다. 범례는 정해진 규칙 안에서 목록을 추가 할 수 있으며 왼쪽에 그림, 오른쪽에 설명이 들어가게 된다. 이 토픽에서는 범례를 빠르게 생성하는 법과 세세하게 설정하는 법을 알아 보자.

 

빠르게 생성하는 법

아래 그림을 예시로 펴보자.

이 그림은 범위를 조절하기 위한 1개의 히스토그램 프레임, 데이터를 표시하기 위한 1개의 그래프, 가우시안 분포를 피팅한 3개의 함수, 전체 분포를 피팅한 1개의 함수, 각 가우시안 분포의 중심을 나타내기 위한 3개의 선(TLine) 으로 이루어져 있다. 이때 범례를 그리는 가장 빠른 방법은 캔버스의 (혹은 패드의) TPad::BuildLegend() 함수를 사용하는 것이다.

TPad::BuildLegend(Double_t x1, Double_t y1, Double_t x2, Double_t x2, Double_t y2, const char* title, Option_t* option);

BuildLegend() 함수를 실행하면 해당 캔버스에 그려진 객체를 그린 순서대로 목록을 가져와 레전드를 만든다. 모든 인수는 생략할 수 있으다. 설명상에는 x1=x2 이고 y1=y2 이면 x1의 폭, y1의 높이를 가지는 범례를 만들고 다른 그림이 그려져있는 부분과 겹치지 않게 위치를 선택한다고 한다.

Automatic placement of the legend

If x1 is equal to x2 and y1 is equal to y2 the legend will be automatically placed to avoid overlapping with the existing primitives already displayed. x1 is considered as the width of the legend and y1 the height. By default the legend is automatically placed with width = x1x2 = 0.3 and height = y1y2 = 0.21.

길이의 단위는 캔버스의 폭(x) 혹은 높이(y) 가 1이 되는 것으로 정의한다. title은 범례의 제목이며 그리고 option은 그림의 객체의 어떤 특징을 나타낼지 정한다. 

  • p : 마커
  • l : 선
  • f : 범위 색칠
  • e : 에러바

중 중복선택 할 수 있다. 범례의 설명은 객체의 제목(fTitle)을 가지고 오는데 제목이 없는 객체라면 이름(fName)을, 이름을 정할 수 없는 객체라면 클래스 이름을 가지고 온다. 

위 그림에서 0.3의 폭과 0.45 의 높이를 가지는 레전드를 생성해서 확인해 보면 다음과 같은 결과를 얻을 수 있다.

{
    ...
    auto lg = gPad -> BuildLegend(0.3,0.45,0.3,0.45,"","pl");
    lg -> Draw();
}

 폭과 높이를 변경해 가면서 실험 해본 결과 자동 위치 선택 기능은 생각보다 아쉬운 결과를 보여주었다. 적당한 x1, y1, x2, y2 을 선택해 주는것이 더 좋아보인다.

{
    ...
    auto lg = gPad -> BuildLegend(0.7,0.55,0.95,0.95,"","pl");
    lg -> Draw();
}

 BuildLegend() 함수를 사용하면 범례를 빠르게 생성하는 만큼 다음과 같은 있다.

 

  • 범례에 넣을 객체를 선택할 수 없다.
  • 그린 순서대로 목록이 생성된다.
  • 설명을 쓰는데 한계가 있다.
  • 각 목록의 그림 옵션을 설정할 수 없다.
  • 그림을 그릴 때 "PLC", "PFC", "PMC" 등의 Draw 옵션을 사용할 수 없다.
하나하나 설정하기

TLegend 객체를 생성하고 객체 하나하나를 선택해서 넣는 것은 TLegend::AddEntry() 함수를 사용한다.

TLegend::AddEntry(const TObject* obj, const char* label, Option_t option)

첫번째 인수로 범례에 넣은 객체를 넣고 두번째 인수에 설명을 그리고 option 으로는 "plfe" 를 중복 선택하여 넣어주면 된다.

{
    ...
    auto lg = new TLegend(0.7,0.55,0.95,0.95);
    lg -> AddEntry(graph, "Data", "pe");
    lg -> AddEntry(fit1, "Particle-1 fit", "l" );
    lg -> AddEntry(fit2, "Particle-2 fit", "l" );
    lg -> AddEntry(fit3, "Particle-3 fit", "l" );
    lg -> AddEntry(fitTotal, "Total fit", "l");
    lg -> Draw();
}

 혹시라도 캔버스의 안쪽 프레임에 범례를 맞추고 싶은 생각이 있다면 다음과 같이 맞출 수 있다.

{
    ...
    auto xIF1 = cvs -> GetUxmin() + cvs -> GetLeftMargin();
    auto xIF2 = cvs -> GetUxmax() - cvs -> GetRightMargin();
    auto yIF1 = cvs -> GetUymin() + cvs -> GetBottomMargin();
    auto yIF2 = cvs -> GetUymax() - cvs -> GetTopMargin();
    auto dx = xIF2 - xIF1;
    auto dy = yIF2 - yIF1;
    auto x1 = xIF1 + 0.6*dx;
    auto x2 = xIF2;
    auto y1 = yIF1 + 0.6*dy;
    auto y2 = yIF2;
    auto lg = new TLegend(x1, y1, x2, y2);
    lg -> AddEntry(graph, "Data", "pe");
    lg -> AddEntry(fit1, "Particle-1 fit", "l");
    lg -> AddEntry(fit2, "Particle-2 fit", "l");
    lg -> AddEntry(fit3, "Particle-3 fit", "l");
    lg -> AddEntry(fitTotal, "Total fit", "l");
    lg -> Draw();
}

이 외에도 아래와 같이 테두리, 글씨체, 글자 크기, 단, 그림과 설명의 비율(margin), 객체 없이 빈 그림으로 등록, 수식 등을 설정할 수 있다.

{
    ...
    auto xIF1 = cvs->GetUxmin() + cvs->GetLeftMargin();
    auto xIF2 = cvs->GetUxmax() - cvs->GetRightMargin();
    auto yIF1 = cvs->GetUymin() + cvs->GetBottomMargin();
    auto yIF2 = cvs->GetUymax() - cvs->GetTopMargin();
    auto dx = xIF2 - xIF1;
    auto dy = yIF2 - yIF1;
    auto x1 = xIF1 + 0.3*dx;
    auto x2 = xIF2 - 0.01;
    auto y1 = yIF1 + 0.56*dy;
    auto y2 = yIF2 - 0.01;
    auto lg = new TLegend(x1,y1,x2,y2);
    lg -> AddEntry(graph,"Data","pe");
    lg -> AddEntry(fitTotal, "Total fit","l");
    lg -> AddEntry(fit1, "Particle-1 fit","l");
    lg -> AddEntry((TObject*)nullptr,Form("#mu_{1} = %.2f",fit1->GetParameter(1)),"");
    lg -> AddEntry(fit2, "Particle-2 fit","l");
    lg -> AddEntry((TObject*)nullptr,Form("#mu_{2} = %.2f",fit2->GetParameter(1)),"");
    lg -> AddEntry(fit3, "Particle-3 fit","l");
    lg -> AddEntry((TObject*)nullptr,Form("#mu_{3} = %.2f",fit3->GetParameter(1)),"");
    lg -> SetBorderSize(0);
    lg -> SetTextFont(132);
    lg -> SetTextSize(0.050);
    lg -> SetNColumns(2);
    lg -> SetMargin(0.3);
    lg -> Draw();
}

 

참고자료

댓글

댓글 본문
버전 관리
ejungwoo
현재 버전
선택 버전
graphittie 자세히 보기