MEP28: Axes.boxplot에서 복잡성 제거 #
상태 번호
논의
브랜치 및 풀 리퀘스트 #
다음은 이 MEP와 관련된 공개 PR 또는 분기 목록입니다.
다음 에서 중복된 통계 kwargs 사용 중단
Axes.boxplot
: https://github.com/phobson/matplotlib/tree/MEP28-initial-deprecations중복 스타일 옵션 사용 중단
Axes.boxplot
: https://github.com/phobson/matplotlib/tree/MEP28-initial-deprecations2D NumPy 배열을 입력으로 전달하지 않음: 없음
전처리 및 후처리 옵션 추가
cbook.boxplot_stats
: https://github.com/phobson/matplotlib/tree/boxplot-stat-transformscbook.boxplot_stats
kwargs 를 통한 노출Axes.boxplot
: 없음다음 에서 중복된 통계적 kwargs 제거
Axes.boxplot
: 없음중복 스타일 옵션 제거
Axes.boxplot
: 없음나머지 논의사항 : 없음
초록 #
지난 몇 번의 릴리스에서 Axes.boxplot
완전히 사용자 지정 가능한 아티스트 스타일 지정 및 통계 계산을 지원하기 위해 메서드가 복잡해졌습니다. 이로 인해 Axes.boxplot
여러 부분으로 분리됩니다. 상자 그림을 그리는 데 필요한 통계는 에서 계산되는
cbook.boxplot_stats
반면 실제 아티스트는 에서 그려집니다 Axes.bxp
. 원래 방법 은 사용자 제공 데이터를 에 전달하고 , 결과를 에 제공하고, boxplot 플롯의 각 측면에 대한 스타일 정보를 전처리 Axes.boxplot
하는 가장 공개적인 API로 남아 있습니다.cbook.boxplot_stats
Axes.bxp
이 MEP는 합당한 이전 버전과의 호환성을 유지하면서 추가된 복잡성을 롤백하고 API를 단순화하기 위한 경로를 설명합니다.
자세한 설명 #
현재 이 Axes.boxplot
방법은 사용자가 플롯에 그려질 각 상자에 대한 중앙값과 신뢰 구간을 지정할 수 있는 매개변수를 허용합니다. 이는 고급 사용자가 matplotlib에서 제공하는 간단한 방법과 다른 방식으로 계산된 통계를 제공할 수 있도록 제공되었습니다. 그러나 이 입력을 처리하려면 데이터 구조의 형식이 그려야 하는 것과 일치하는지 확인하는 복잡한 논리가 필요합니다. 현재 이 논리에는 for 루프를 사용하여 최대 5단계까지 중첩된 9개의 개별 if/else 문이 포함되어 있으며 최대 2개의 오류가 발생할 수 있습니다. Axes.bxp
이러한 매개변수는 관련 통계가 포함된 사전 목록에서 상자 그림을 그리는 방법을 만들기 전에 추가되었습니다 . Matplotlib는 또한 다음을 통해 이러한 통계를 계산하는 함수를 제공합니다.cbook.boxplot_stats
. 이제 고급 사용자는 a) 에 필요한 통계를 계산하는 자체 함수를 작성
Axes.bxp
하거나 b) 에서 반환된 출력을 수정 cbook.boxplots_stats
하여 플롯 아티스트의 위치를 완전히 사용자 지정할 수 있습니다. 이러한 유연성을 통해 중앙값과 해당 신뢰 구간만 수동으로 지정하는 매개변수는 이전 버전과의 호환성을 위해 유지됩니다.
의 두 가지 역할이 계산용과 그리기
용 Axes.boxplot
으로 분할된
것과 거의 동시에 상자 그림의 모든 구성 요소 그리기를 개별적으로 토글하는 매개변수 와 해당 아티스트의 스타일을 개별적으로 구성하는 매개변수를 허용하도록 작성되었습니다. 그러나 이전 버전과의 호환성을 유지하기 위해 매개변수(이전에 전단지의 기호를 지정하는 데 사용됨)는 그대로 유지되었습니다. 이 매개변수 자체에는 에서 지정한 기본 스타일 의 새 매개변수와 매개변수 를 조정하는 상당히 복잡한 논리가 필요합니다 .cbook.boxplot_stats
Axes.bxp
Axes.boxplot
Axes.bxp
sym
sym
flierprops
matplotlibrc
이 MEP는 초보자와 고급 사용자 모두를 위해 상자 그림 생성을 극적으로 단순화하려고 합니다. 여기서 제안된 변경 사항은 seaborn과 같은 다운스트림 패키지에서도 사용할 수 있습니다. seaborn은 사용자가 seaborn API를 통해 매개 변수의 임의 사전을 기본 matplotlib 함수에 전달할 수 있도록 현명하게 허용하기 때문입니다.
이는 다음과 같은 방법으로 달성됩니다.
cbook.boxplot_stats
사전 및 사후 계산 변환 함수가 전달될 수 있도록 수정됩니다(예: 로그 정규 분포 데이터의 경우)np.log
.np.exp
Axes.boxplot
그것들을 수락하고 순진하게 전달하도록 수정될 것입니다cbook.boxplots_stats
(Alt: stat 함수와 선택적 매개변수의 사전 전달).의 오래된 매개변수
Axes.boxplot
는 더 이상 사용되지 않으며 나중에 제거됩니다.
중요성 #
위스커의 한계는 산술적으로 계산되기 때문에 상자 및 위스커 플롯에는 정규성에 대한 암묵적인 가정이 있습니다. 이것은 주로 이상값으로 분류되는 데이터 포인트에 영향을 미칩니다.
상자 그림을 그리는 데 사용되는 데이터 및 결과에 대한 변환을 허용하면 데이터가 정규 분포에 적합하지 않은 것으로 알려진 경우 사용자가 해당 가정을 거부할 수 있습니다.
다음은 Axes.boxplot
이러한 유형의 변환에 따라 로그 정규 데이터의 이상값을 다르게 분류하는 방법의 예입니다.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cbook
np.random.seed(0)
fig, ax = plt.subplots(figsize=(4, 6))
ax.set_yscale('log')
data = np.random.lognormal(-1.75, 2.75, size=37)
stats = cbook.boxplot_stats(data, labels=['arithmetic'])
logstats = cbook.boxplot_stats(np.log(data), labels=['log-transformed'])
for lsdict in logstats:
for key, value in lsdict.items():
if key != 'label':
lsdict[key] = np.exp(value)
stats.extend(logstats)
ax.bxp(stats)
fig.show()
![../../_images/MEP28-1.png](/stable/_images/MEP28-1.png)
구현 #
변환 함수를 cbook.boxplots_stats
# 에 전달
이 MEP는 두 개의 매개변수(예: transform_in
및
transform_out
boxplot 함수에 대한 통계를 계산하는 요리책 함수에 추가됨)를 제안합니다. 이들은 선택적 키워드 전용 인수이며 사용자가 생략할 때 쉽게 no-op로 설정할 수 있습니다. 함수가 전달된 데이터의 각 하위 집합을 통해 루프를 돌 때 함수가 데이터에 적용됩니다 . 통계 사전 목록이 계산된 후
함수는 사전의 각 값에 적용됩니다.lambda x: x
transform_in
boxplot_stats
transform_out
그런 다음 이러한 변환
Axes.boxplot
을 해당 메서드의 복잡성에 거의 영향을 주지 않고 호출 서명에 추가할 수 있습니다. 에 직접 전달할 수 있기 때문 cbook.boxplot_stats
입니다. 또는 Axes.boxplot
선택적 통계 함수 kwarg 및 직접 전달될 매개변수 사전을 허용하도록 수정될 수 있습니다.
구현의 이 시점에서 사용자와 seaborn과 같은 외부 라이브러리는 Axes.boxplot
메서드를 통해 완전한 제어를 가집니다. 더 중요한 것은 적어도 seaborn은 사용자가 이러한 새로운 옵션을 활용할 수 있도록 API를 변경할 필요가 없다는 것입니다.
Axes.boxplot
API 및 기타 기능 단순화 #
boxplot 방법을 단순화하는 것은 주로 사용 중단 후 중복 매개변수를 제거하는 것으로 구성됩니다. Axes.boxplot
선택적으로 다음 단계에는 와 사이의 사소한 용어 불일치를 수정하는 작업이 포함됩니다 Axes.bxp
.
더 이상 사용되지 않고 제거될 매개변수는 다음과 같습니다.
usermedians
- 10 SLOC, 3if
블록,for
루프 로 처리
conf_intervals
- 15개의 SLOC, 6개의if
블록,for
루프 로 처리
sym
- 12개의 SLOC, 4if
블록 으로 처리
옵션을 제거하면 sym
나머지 스타일링 매개변수를 처리하는 모든 코드를 로 이동할 수 Axes.bxp
있습니다. 이것은 복잡성을 제거하지는 않지만 Axes.bxp
, cbook.boxplot_stats
, 및 간의 단일 책임 원칙을 강화합니다 Axes.boxplot
.
또한 notch
매개변수의 이름 shownotches
을 과 일치하도록 변경할 수 있습니다 Axes.bxp
. 이러한 종류의 정리는 한 단계 더 나아가 새 매개변수 에 전달된 kwargs로 롤링될 수 있습니다 whis
.bootstrap
autorange
statfxn
이전 버전과의 호환성 #
이 MEP를 구현하면 결국 이전 버전과 호환되지 않으며 키워드 매개변수
usermedians
, conf_intervals
및 가 제거 sym
됩니다. GitHub의 커서 검색에 따르면 usermedians
, conf_intervals
는 모두 matplotlib에 대한 매우 강력한 지식을 가지고 있는 것으로 보이는 소수의 사용자에 의해 사용됩니다. 강력한 사용 중단 주기는 이러한 사용자가 새 API로 마이그레이션할 수 있는 충분한 시간을 제공해야 합니다.
그러나 더 이상 사용되지 sym
않으면 matplotlib 사용자 기반에 훨씬 더 광범위하게 도달할 수 있습니다.
일정 #
가속화된 타임라인은 다음과 같습니다.
v2.0.1에 변환 추가
cbook.boxplots_stats
, 노출Axes.boxplot
v2.1.0 초기 지원 중단 및 2D NumPy 배열을 입력으로 사용
2D NumPy 배열을 입력으로 사용. 2D 배열 주변의 의미 체계는 일반적으로 혼란스럽습니다.
usermedians
,conf_intervals
,sym
매개변수
v2.2.0
usermedians
,conf_intervals
,sym
매개변수 제거다른 매개변수와 일관성을 유지하기
notch
위해 지원 중단shownotches
Axes.bxp
- v2.3.0
notch
매개변수 제거모든 스타일을 이동하고 아티스트가 논리를 전환하는 것은
Axes.bxp
와 사이 의Axes.boxplot
중개인에 지나지 않습니다.Axes.bxp
cbook.boxplots_stats
사용자에게 예상되는 영향 #
위에 설명된 대로 더 이상 사용되지 않으며 usermedians
소수의 conf_intervals
사용자에게 영향을 미칠 수 있습니다. 영향을 받을 사용자는 거의 확실하게 변화에 적응할 수 있는 고급 사용자입니다.
이 sym
옵션을 사용하지 않으면 더 많은 사용자를 가져올 수 있으며 이에 대한 커뮤니티 피드백을 수집하기 위해 노력해야 합니다.
다운스트림 라이브러리에 예상되는 영향 #
소스 코드(2016년 10월 17일 현재 GitHub 마스터)는 seaborn 및 python-ggplot에 대해 검사되어 이러한 변경 사항이 사용에 영향을 미치는지 확인했습니다. 이 MEP에서 제거하도록 지정된 매개변수는 seaborn에서 사용되지 않습니다. matplotlib의 boxplot 기능을 사용하는 seaborn API는 사용자가 **kwargs
matplotlib의 API를 통해 임의로 전달할 수 있도록 합니다. 따라서 최신 matplotlib 설치를 사용하는 노련한 사용자는 이 MEP의 결과로 추가된 새로운 기능을 최대한 활용할 수 있습니다.
Python-ggplot은 boxplot을 그리는 자체 기능을 구현했습니다. 따라서 이 MEP를 구현한 결과로 영향을 받을 수 없습니다.
대안 #
테마의 변형 #
이 MEP는 느슨하게 결합된 몇 가지 구성 요소로 나눌 수 있습니다.
사전 및 사후 계산 변환 기능 허용
cbook.boxplot_stats
Axes.boxplot
API 에서 해당 변환 노출중복 통계 옵션 제거
Axes.boxplot
모든 스타일링 매개변수 처리를 에서
Axes.boxplot
로 전환합니다Axes.bxp
.
이 접근 방식을 사용하면 #2가 종속되고 #1과 #4가 #3에 종속됩니다.
#2에 대한 두 가지 접근 방식이 있습니다. 첫 번째이자 가장 직접적인 방법은 in 의 new transform_in
및 transform_out
매개변수
를 미러링 하고 직접 전달하는 것입니다.cbook.boxplot_stats
Axes.boxplot
두 번째 방법은 statfxn
및 statfxn_args
매개변수를 에 추가하는 것 Axes.boxplot
입니다. 이 구현에서 의 기본값은 statfxn
이지만 cbook.boxplot_stats
사용자는 자신의 기능을 전달할 수 있습니다. 그러면 transform_in
and transform_out
가 매개변수의 요소로 전달됩니다 statfxn_args
.
def boxplot_stats(data, ..., transform_in=None, transform_out=None):
if transform_in is None:
transform_in = lambda x: x
if transform_out is None:
transform_out = lambda x: x
output = []
for _d in data:
d = transform_in(_d)
stat_dict = do_stats(d)
for key, value in stat_dict.item():
if key != 'label':
stat_dict[key] = transform_out(value)
output.append(d)
return output
class Axes(...):
def boxplot_option1(data, ..., transform_in=None, transform_out=None):
stats = cbook.boxplot_stats(data, ...,
transform_in=transform_in,
transform_out=transform_out)
return self.bxp(stats, ...)
def boxplot_option2(data, ..., statfxn=None, **statopts):
if statfxn is None:
statfxn = boxplot_stats
stats = statfxn(data, **statopts)
return self.bxp(stats, ...)
두 경우 모두 사용자가 다음을 수행할 수 있습니다.
fig, ax1 = plt.subplots()
artists1 = ax1.boxplot_optionX(data, transform_in=np.log,
transform_out=np.exp)
my_box_stats
그러나 옵션 2를 사용하면 멋진 BCA 신뢰 구간과 수염이 데이터의 일부 특성에 따라 다르게 설정된 완전히 사용자 정의 통계 함수(예: )를 작성할 수 있습니다 .
이는 현재 API에서 사용할 수 있습니다.
fig, ax1 = plt.subplots()
my_stats = my_box_stats(data, bootstrap_method='BCA',
whisker_method='dynamic')
ax1.bxp(my_stats)
옵션 2를 사용하면 더 간결해질 것입니다.
fig, ax = plt.subplots()
statopts = dict(transform_in=np.log, transform_out=np.exp)
ax.boxplot(data, ..., **statopts)
사용자는 자신의 함수를 전달하여 통계를 계산할 수도 있습니다.
fig, ax1 = plt.subplots()
ax1.boxplot(data, statfxn=my_box_stats, bootstrap_method='BCA',
whisker_method='dynamic')
위의 예에서 옵션 2는 미미한 이점만 있는 것처럼 보이지만 seaborn과 같은 다운스트림 라이브러리의 맥락에서 다음과 같은 이점이 seaborn에 대한 패치 없이 가능하므로 이점이 더 분명합니다.
import seaborn
tips = seaborn.load_data('tips')
g = seaborn.factorplot(x="day", y="total_bill", hue="sex", data=tips,
kind='box', palette="PRGn", shownotches=True,
statfxn=my_box_stats, bootstrap_method='BCA',
whisker_method='dynamic')
이러한 유형의 유연성은 현재 세 가지 기능에서 전체 boxplot API를 분할하려는 의도였습니다. 그러나 실제로 seaborn과 같은 다운스트림 라이브러리는 분할 이전으로 거슬러 올라가는 matplotlib 버전을 지원합니다. 따라서 유연성을 조금 더 추가
Axes.boxplot
하면 다운스트림 라이브러리 관리자의 개입 없이 최신 matplotlib 설치를 통해 다운스트림 라이브러리 사용자에게 모든 기능을 노출할 수 있습니다.
적게 하기 #
또 다른 명백한 대안은 및 에서 추가된 사전 및 사후 계산 변환 기능을 생략하고 cbook.boxplot_stats
위에서
Axes.boxplot
설명한 대로 중복 통계 및 스타일 매개변수를 간단히 제거하는 것입니다.
아무것도 안하고 #
인생의 많은 일과 마찬가지로 아무것도 하지 않는 것도 선택 사항입니다. 이것은 우리가 단순히 사용자와 다운스트림 라이브러리 사이의 분할을 활용 cbook.boxplot_stats
하고 Axes.bxp
그에 대한 인터페이스를 제공하는 방법을 결정할 수 있도록 옹호한다는 것을 의미합니다.