Matplotlib 을 이용한 대화형 히스토그램 생성

Beginner

This tutorial is from open-source community. Access the source code

소개

이 랩에서는 Matplotlib 을 사용하여 대화형 히스토그램을 만드는 방법을 배웁니다. 대화형 기능은 ECMAScript (JavaScript) 로 인코딩되어 후처리 단계에서 SVG 코드에 삽입됩니다. 결과 히스토그램은 범례 마커를 클릭하여 막대를 숨기거나 표시할 수 있습니다.

VM 팁

VM 시작이 완료되면 왼쪽 상단을 클릭하여 Notebook 탭으로 전환하여 실습을 위해 Jupyter Notebook에 액세스하십시오.

때로는 Jupyter Notebook 이 로딩을 완료하는 데 몇 초 정도 기다려야 할 수 있습니다. Jupyter Notebook 의 제한 사항으로 인해 작업의 유효성 검사는 자동화할 수 없습니다.

학습 중에 문제가 발생하면 언제든지 Labby 에게 문의하십시오. 세션 후 피드백을 제공해주시면 문제를 신속하게 해결해 드리겠습니다.

히스토그램, 범례 및 제목 생성

먼저, Matplotlib 을 사용하여 히스토그램, 범례 및 제목을 생성합니다. 또한 set_gid() 메서드를 사용하여 각 객체에 ID 를 할당합니다. 이는 Python 에서 생성된 Matplotlib 객체와 두 번째 단계에서 파싱되는 해당 SVG 구조를 연결하는 데 도움이 됩니다.

import matplotlib.pyplot as plt
import numpy as np

## Fixing random state for reproducibility
np.random.seed(19680801)

## Create histogram, legend, and title
plt.figure()
r = np.random.randn(100)
r1 = r + 1
labels = ['Rabbits', 'Frogs']
H = plt.hist([r, r1], label=labels)
containers = H[-1]
leg = plt.legend(frameon=False)
plt.title("From a web browser, click on the legend\n"
          "marker to toggle the corresponding histogram.")

## Assign IDs to the SVG objects we'll modify
hist_patches = {}
for ic, c in enumerate(containers):
    hist_patches[f'hist_{ic}'] = []
    for il, element in enumerate(c):
        element.set_gid(f'hist_{ic}_patch_{il}')
        hist_patches[f'hist_{ic}'].append(f'hist_{ic}_patch_{il}')

## Set IDs for the legend patches
for i, t in enumerate(leg.get_patches()):
    t.set_gid(f'leg_patch_{i}')

## Set IDs for the text patches
for i, t in enumerate(leg.get_texts()):
    t.set_gid(f'leg_text_{i}')

히스토그램에 대화형 기능 추가

다음으로, ECMAScript (JavaScript) 를 사용하여 SVG 코드를 수정하여 히스토그램에 대화형 기능을 추가합니다. set() 메서드를 사용하여 패치 및 텍스트 객체에 속성을 추가합니다. 또한 각 히스토그램에 속하는 패치 ID 를 저장하는 전역 변수 container를 생성합니다. 마지막으로, 각 히스토그램의 모든 패치의 가시성 속성과 마커 자체의 불투명도를 설정하는 함수 toggle_hist()를 생성합니다.

from io import BytesIO
import json
import xml.etree.ElementTree as ET

plt.rcParams['svg.fonttype'] = 'none'

## Save SVG in a fake file object
f = BytesIO()
plt.savefig(f, format="svg")

## Create XML tree from the SVG file
tree, xmlid = ET.XMLID(f.getvalue())

## Add attributes to the patch objects
for i, t in enumerate(leg.get_patches()):
    el = xmlid[f'leg_patch_{i}']
    el.set('cursor', 'pointer')
    el.set('onclick', "toggle_hist(this)")

## Add attributes to the text objects
for i, t in enumerate(leg.get_texts()):
    el = xmlid[f'leg_text_{i}']
    el.set('cursor', 'pointer')
    el.set('onclick', "toggle_hist(this)")

## Create script defining the function `toggle_hist`
script = """
<script type="text/ecmascript">
<![CDATA[
var container = %s

function toggle(oid, attribute, values) {
    /* Toggle the style attribute of an object between two values.

    Parameters
    ----------
    oid : str
      Object identifier.
    attribute : str
      Name of style attribute.
    values : [on state, off state]
      The two values that are switched between.
    */
    var obj = document.getElementById(oid);
    var a = obj.style[attribute];

    a = (a == values[0] || a == "") ? values[1] : values[0];
    obj.style[attribute] = a;
    }

function toggle_hist(obj) {

    var num = obj.id.slice(-1);

    toggle('leg_patch_' + num, 'opacity', [1, 0.3]);
    toggle('leg_text_' + num, 'opacity', [1, 0.5]);

    var names = container['hist_'+num]

    for (var i=0; i < names.length; i++) {
        toggle(names[i], 'opacity', [1, 0])
    };
    }
]]>
</script>
""" % json.dumps(hist_patches)

## Add a transition effect
css = tree.find('.//{http://www.w3.org/2000/svg}style')
css.text = css.text + "g {-webkit-transition:opacity 0.4s ease-out;" + \
    "-moz-transition:opacity 0.4s ease-out;}"

## Insert the script and save to file
tree.insert(0, ET.XML(script))
ET.ElementTree(tree).write("svg_histogram.svg")

대화형 히스토그램 보기

마지막으로, 웹 브라우저에서 SVG 파일을 열어 대화형 히스토그램을 볼 수 있습니다. 막대를 숨기거나 표시하려면 범례 마커를 클릭하십시오.

요약

이 랩에서는 Matplotlib 을 사용하여 대화형 히스토그램을 만드는 방법을 배웠습니다. SVG 코드를 수정하여 ECMAScript (JavaScript) 를 사용하여 히스토그램에 대화형 기능을 추가했습니다. 결과 히스토그램은 범례 마커를 클릭하여 숨기거나 표시할 수 있는 막대를 갖습니다.