복붙노트

[PYTHON] Matplotlib : 그림 개체를 사용하여 그림 초기화

PYTHON

Matplotlib : 그림 개체를 사용하여 그림 초기화

특정 실험을위한 플롯 도구 클래스를 작성 중입니다. 나는 현재 두 가지 플롯 방법, 즉 imshow ()를 사용하는 정적 플롯과 "영화"포맷을 가지고있다. imshow ()를 사용합니다.

두 가지 방법과 미래의 방법 모두, 필자가 작성할 수있는 특정 플로팅 방법에 대해 동일한 매개 변수를 얻습니다. 플롯 클래스가 사용될 때 config 객체에 모든 매개 변수가 있습니다.

필자는 모든 플롯 방법에서 코드를 다시 작성하고 싶지 않습니다. vmin, vmax, extent_dim, Xlocs, Xlabels, Ylocs, Ylabels와 같은 args가 설정된 객체 (AxesImage에서 생각하는)를 초기화하고 싶습니다.

그런 다음 그 객체를 다른 특정 작업을 수행하는 다양한 방법으로 전달합니다. 이 일을하는 법을 모르겠다.

import matplotlib.pyplot as plt

data = data_dict[type] # could be real part of a complex number, phase, or the mag...
v_min, v_max = self.get_data_type_scale(data_dict, Type)
freq = data_dict['freq']

# essentially sets the aspect of the plot since the x and y resolutions could be different   
extent_dim = self._get_extent(2)
# gets the labels for physical dimensions of the experiment
Xlocs,Xlabels,Ylocs,Ylabels = self._get_ticks(5,5,extent_dim)

# in the guts of a plot method, the basic idea is the call below.  

plt.imshow(data[0,:,:],cmap='jet',vmin=v_min,...
vmax=v_max,origin='lower', extent = extent_dim)

plt.title('Type:  %s  Freq: %.3e Hz' %(Type,data_dict['freq'][0]) )
plt.xticks(Xlocs, Xlabels)
plt.yticks(Ylocs,Ylabels)

해결법

  1. ==============================

    1.matplotlib의 아키텍처를 먼저 이해해야합니다 (창립자 및 현재 수석 개발자가 작성한 기사 참조). 렌더링과 하드웨어와의 통신을 다루는 백엔드 계층의 하단. 그 레이어의 맨 위에는 백엔드 객체에게 무엇을해야하는지 알려주는 방법을 알고있는 아티스트가 있습니다. 그 레이어 위에는 MATLAB을 모방 한 pyplot 상태 머신 인터페이스가 있습니다.

    matplotlib의 아키텍처를 먼저 이해해야합니다 (창립자 및 현재 수석 개발자가 작성한 기사 참조). 렌더링과 하드웨어와의 통신을 다루는 백엔드 계층의 하단. 그 레이어의 맨 위에는 백엔드 객체에게 무엇을해야하는지 알려주는 방법을 알고있는 아티스트가 있습니다. 그 레이어 위에는 MATLAB을 모방 한 pyplot 상태 머신 인터페이스가 있습니다.

    그림에서 보는 모든 것을 내부적으로 아티스트로 표현하고 아티스트는 다른 아티스트를 포함 할 수 있습니다. 예를 들어, Axes 객체는 척추, 눈금, 레이블, 선 또는 이미지 등 축 인 Children 아티스트를 추적하며 Axes 객체는 Figure 객체의 자식입니다. 그림을 그릴 그림을 말할 때 (fig.canvas.draw ()를 통해) 모든 아티스트들은 재귀 적으로 그려진다.

    이 디자인의 한 가지 단점은 아티스트의 인스턴스화가 정확히 하나의 그림에 포함될 수 있으며 (그림 사이를 이동하는 것이 어렵다는 것입니다) AxesImage 객체를 만든 다음 계속 재사용 할 수 없다는 것입니다.

    이 디자인은 아티스트가 알고있는 것을 구분합니다. Axes 객체는 눈금 위치, 레이블 및 표시 범위 (Axis 객체에 대해 알고 있지만 잡초에 더 많이 포함됨)와 같은 항목을 알고 있습니다. vmin 및 vmax와 같은 것은 AxesImage가 추적하는 Normalize (doc) 객체에 캡슐화됩니다. 즉, 귀하의 목록에있는 모든 것을 다루는 방법을 분리해야합니다.

    여기에 공장과 같은 패턴이나 카레와 같은 패턴을 사용하는 것이 좋습니다.

    공장과 같은 :

    def set_up_axes(some, arguements):
        '''
        Factory to make configured axes (
        '''
        fig, ax = plt.subplots(1, 1) # or what ever layout you want
        ax.set_*(...)
        return fig, ax
    
    
    my_norm = matplotlib.colors.Normalize(vmin, mmax) # or write a factory to do fancier stuff
    fig, ax = set_up_axes(...)
    ax.imshow(..., norm=my_norm)
    fig2, ax2 = set_up_axes(...)
    ax2.imshow(..., norm=mynorm)
    

    kwargs의 전체 집합을 정리하면 쉽게 다시 사용할 수 있습니다.

    my_imshow_args = {'extent':[...],
                      'interpolation':'nearest',
                      'norm': my_norm,
                       ...}
    
    ax2.imshow(..., **my_imshow_args)
    

    카레 같은 :

    def my_imshow(im, ax=None, *args, **kwargs):
        if ax is None:
            ax = plt.gca()
        # do all of your axes set up
        ax.set_xlim(..)
    
        # set default vmin and vmax
        # you can drop some of these conditionals if you don't want to be
        # able to explicitly override the defaults
        if 'norm' not in kwargs:
            vmin = kwargs.pop('vmin', None)
            vmax = kwargs.pop('vmax', None)
            if vmin is None:
                vmin = default_vmin # or what ever
            if vmax is None:
                vmax = default_vmax
            my_norm = matplotlib.colors.Normalize(vmin, mmax)
            kwargs['norm'] = norm
    
        # add a similar block for `extent` 
        # or any other kwargs you want to change the default of
    
        ax.figure.canvas.draw() # if you want to force a re-draw
        return ax.imshow(im, *args, **kwargs)
    

    당신이 슈퍼 영리하고 싶다면 당신의 버전으로 monkey-patch plt.imshow를 할 수 있습니다.

    plt.imshow = my_imshow
    

    또한 rcParams 인터페이스가있어 많은 비트와 매트랩의 기본값을 전역 적으로 변경할 수 있습니다.

    그리고 이것을 달성하기위한 또 다른 방법은 (부분적으로)

  2. ==============================

    2.그림을보기 위해서는 fig.canvas.draw ()를 사용하십시오. fig는 Figure 클래스의 인스턴스입니다. fig.canvas.draw ()는 대화 형 쉘의 API 버전입니다 (read : pylab). function draw ()

    그림을보기 위해서는 fig.canvas.draw ()를 사용하십시오. fig는 Figure 클래스의 인스턴스입니다. fig.canvas.draw ()는 대화 형 쉘의 API 버전입니다 (read : pylab). function draw ()

    AxesImage 객체에서 Axes 또는 Figure를 가져와야하는 경우 im.get_axes () 또는 im.get_figure ()를 각각 호출 할 수 있습니다.

    "좋은"객체 지향 코드를 작성하는 것만 큼 사용자 인터페이스 예제를 시작하는 것이 좋습니다.

  3. from https://stackoverflow.com/questions/18284296/matplotlib-using-a-figure-object-to-initialize-a-plot by cc-by-sa and MIT license