· 

matplotlibで棒グラフ間の有意差の描画をする

(著)山たー

 

とりあえずメモ。2群比較とかで有意差の描画をPythonでどうやるか調べていたら、いい関数の実装を見つけた。

(参考)Indicating the statistically significant difference in bar graph

 

コード

from scipy import stats
import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)

def barplot_annotate_brackets(num1, num2, data, center, 
                              height, yerr=None, dh=.05, 
                              barh=.05, fs=None, maxasterix=None):
    """ 
    Annotate barplot with p-values.
 
    :param num1: number of left bar to put bracket over
    :param num2: number of right bar to put bracket over
    :param data: string to write or number for generating asterixes
    :param center: centers of all bars (like plt.bar() input)
    :param height: heights of all bars (like plt.bar() input)
    :param yerr: yerrs of all bars (like plt.bar() input)
    :param dh: height offset over bar / bar + yerr in axes coordinates (0 to 1)
    :param barh: bar height in axes coordinates (0 to 1)
    :param fs: font size
    :param maxasterix: maximum number of asterixes to write (for very small p-values)
    """
 
    if type(data) is str:
        text = data
    else:
        # * is p < 0.05
        # ** is p < 0.005
        # *** is p < 0.0005
        # etc.
        text = ''
        p = .05
 
        while data < p:
            text += '*'
            p /= 10.
 
            if maxasterix and len(text) == maxasterix:
                break
 
        if len(text) == 0:
            text = 'n. s.'
 
    lx, ly = center[num1], height[num1]
    rx, ry = center[num2], height[num2]
 
    if yerr:
        ly += yerr[num1]
        ry += yerr[num2]
 
    ax_y0, ax_y1 = plt.gca().get_ylim()
    dh *= (ax_y1 - ax_y0)
    barh *= (ax_y1 - ax_y0)
 
    y = max(ly, ry) + dh
 
    barx = [lx, lx, rx, rx]
    bary = [y, y+barh, y+barh, y]
    mid = ((lx+rx)/2, y+barh)
 
    plt.plot(barx, bary, c='black')
 
    kwargs = dict(ha='center', va='bottom')
    if fs is not None:
        kwargs['fontsize'] = fs
 
    plt.text(*mid, text, **kwargs)
     
""" main """
# Generate toy data
x0 = np.random.normal(loc=1.9, scale=0.4, size=100)
x1 = np.random.normal(loc=2, scale=0.3, size=100)
x2 = np.random.normal(loc=2.5, scale=0.8, size=50)

# Welch’s t-test
t01_value, p01_value = stats.ttest_ind(x0, x1, equal_var=False)
t02_value, p02_value = stats.ttest_ind(x0, x2, equal_var=False)
t12_value, p12_value = stats.ttest_ind(x1, x2, equal_var=False)


""" plot """
heights = [np.mean(x0), np.mean(x1), np.mean(x2)]
std = [np.std(x0), np.std(x1), np.std(x2)]
label = ["x0", "x1", "x2"]
width = 0.8 # the width of the bars
bars = np.arange(len(heights))
 
plt.figure(figsize=(4, 5))
plt.bar(bars, heights, width, tick_label=label, yerr=std,
        align='center', alpha=0.5, ecolor='black', capsize=5)
plt.ylim(0, 5)
barplot_annotate_brackets(0, 1, p01_value, bars,
                          heights, yerr=std)
barplot_annotate_brackets(0, 2, 'p < 0.001', bars,
                          heights, yerr=std)
barplot_annotate_brackets(1, 2, p12_value, bars,
                          heights, yerr=std,dh=0.2)
plt.tight_layout()
plt.savefig("barplot_sig.png")
plt.show()

他に参考にしたサイト

コメントをお書きください

コメント: 5
  • #1

    LFOHP (Wednesday, 10 June 2020 08:42)

    とても興味あります。勉強になります、ありがとうございます。
    コードの理解が少し難しいです。個人的にでもおしえてもらえませんか?メールでもGitHubなどで各コードのコメントをつけてもらえませんか。

  • #2

    Vinay Tomar (Monday, 21 February 2022)

    Hey,

    I’ve been an avid reader of https://omedstu.jimdofree.com/2019/02/11/matplotlib%E3%81%A7%E6%A3%92%E3%82%B0%E3%83%A9%E3%83%95%E9%96%93%E3%81%AE%E6%9C%89%E6%84%8F%E5%B7%AE%E3%81%AE%E6%8F%8F%E7%94%BB%E3%82%92%E3%81%99%E3%82%8B/ for quite some time now – and I really love how detailed and well-researched your guides are.

    I can only imagine the time you spent working on those.
    Anyway, I noticed that you’ve been writing a lot about python lately. I have a resource on learning Python that talks about exactly that.

    Guru99 has a huge list of software learning library across topics like Linux, Java ,PHP ,SQL ,Ethical Hacking, python any more with new courses added every month.

    In this Python for beginners tutorial, you will learn Python installation, variables, Data structure, loops, strings, functions, file handling, Python SciPy, Python JSON, Python with MySQL, matrix, Python List, Python Regex, PyTest, PyQt, multithreading, Python interview questions, and many more interesting Python concepts.

    You can see the full Python tutorial here: https://www.guru99.com/python-tutorials.html

    I think mentioning it would bring some extra value for your readers and give them a wider view of Python.

    As a thankyou, I would be glad to share your page with our 31k Facebook/Twitter/Linkedin Followers.
    Or
    I am happy to do Cross-Promotion.

    Let me know your thoughts. Thanks.
    Regards,
    Vinay
    PS: I am real a person... here is a number to contact me +1 302 308 5151

  • #3

    Vinay Tomar (Monday, 28 February 2022 17:14)

    Hi,
    I wanted to quickly catch up and see if you have received my email below.
    Eagerly awaiting your reply.

    ================== Original Massage ==================
    Hey,

    I’ve been an avid reader of https://omedstu.jimdofree.com/2019/02/11/matplotlib%E3%81%A7%E6%A3%92%E3%82%B0%E3%83%A9%E3%83%95%E9%96%93%E3%81%AE%E6%9C%89%E6%84%8F%E5%B7%AE%E3%81%AE%E6%8F%8F%E7%94%BB%E3%82%92%E3%81%99%E3%82%8B/ for quite some time now – and I really love how detailed and well-researched your guides are.

    I can only imagine the time you spent working on those.
    Anyway, I noticed that you’ve been writing a lot about python lately. I have a resource on learning Python that talks about exactly that.

    Guru99 has a huge list of software learning library across topics like Linux, Java ,PHP ,SQL ,Ethical Hacking, python any more with new courses added every month.

    In this Python for beginners tutorial, you will learn Python installation, variables, Data structure, loops, strings, functions, file handling, Python SciPy, Python JSON, Python with MySQL, matrix, Python List, Python Regex, PyTest, PyQt, multithreading, Python interview questions, and many more interesting Python concepts.

    You can see the full Python tutorial here: https://www.guru99.com/python-tutorials.html

    I think mentioning it would bring some extra value for your readers and give them a wider view of Python.

    As a thankyou, I would be glad to share your page with our 31k Facebook/Twitter/Linkedin Followers.
    Or
    I am happy to do Cross-Promotion.

    Let me know your thoughts. Thanks.
    Regards,
    Vinay
    PS: I am a real person... here is a number to contact me +1 302 308 5151

  • #4

    Vinay Tomar (Thursday, 03 March 2022 20:35)

    Hi,
    How's it going?
    I feel horrible troubling you and I'm starting to feel like a stalker. Much appreciated if you can let me know if you'd Link to us. If not, I won't send you another email.

    ================== Original Massage ==================
    Hey,

    I’ve been an avid reader of https://omedstu.jimdofree.com/2019/02/11/matplotlib%E3%81%A7%E6%A3%92%E3%82%B0%E3%83%A9%E3%83%95%E9%96%93%E3%81%AE%E6%9C%89%E6%84%8F%E5%B7%AE%E3%81%AE%E6%8F%8F%E7%94%BB%E3%82%92%E3%81%99%E3%82%8B/ for quite some time now – and I really love how detailed and well-researched your guides are.

    I can only imagine the time you spent working on those.
    Anyway, I noticed that you’ve been writing a lot about python lately. I have a resource on learning Python that talks about exactly that.

    Guru99 has a huge list of software learning library across topics like Linux, Java ,PHP ,SQL ,Ethical Hacking, python any more with new courses added every month.

    In this Python for beginners tutorial, you will learn Python installation, variables, Data structure, loops, strings, functions, file handling, Python SciPy, Python JSON, Python with MySQL, matrix, Python List, Python Regex, PyTest, PyQt, multithreading, Python interview questions, and many more interesting Python concepts.

    You can see the full Python tutorial here: https://www.guru99.com/python-tutorials.html

    I think mentioning it would bring some extra value for your readers and give them a wider view of Python.

    As a thankyou, I would be glad to share your page with our 41k Facebook/Twitter/Linkedin Followers.
    Or
    I am happy to do Cross-Promotion.

    Let me know your thoughts. Thanks.
    Regards,
    Vinay
    PS: I am a real person... here is a number to contact me +1 302 308 5151

  • #5

    Vinay Tomar (Friday, 11 March 2022 21:18)

    I reached out previously and hadn’t heard back from you yet. This tells me a few things:
    1) You're being chased by a T-rex and haven't had time to respond.
    2) You aren't interested.
    3) You're interested but haven't had a time to respond.
    Whichever one it is, please let me know as I am getting worried! Please respond 1,2, or 3. I do not want to be a bother.

    ================== Original Massage ==================
    Hey,

    I’ve been an avid reader of https://omedstu.jimdofree.com/2019/02/11/matplotlib%E3%81%A7%E6%A3%92%E3%82%B0%E3%83%A9%E3%83%95%E9%96%93%E3%81%AE%E6%9C%89%E6%84%8F%E5%B7%AE%E3%81%AE%E6%8F%8F%E7%94%BB%E3%82%92%E3%81%99%E3%82%8B/ for quite some time now – and I really love how detailed and well-researched your guides are.

    I can only imagine the time you spent working on those.
    Anyway, I noticed that you’ve been writing a lot about python lately. I have a resource on learning Python that talks about exactly that.

    Guru99 has a huge list of software learning library across topics like Linux, Java ,PHP ,SQL ,Ethical Hacking, python any more with new courses added every month.

    In this Python for beginners tutorial, you will learn Python installation, variables, Data structure, loops, strings, functions, file handling, Python SciPy, Python JSON, Python with MySQL, matrix, Python List, Python Regex, PyTest, PyQt, multithreading, Python interview questions, and many more interesting Python concepts.

    You can see the full Python tutorial here: https://www.guru99.com/python-tutorials.html
    I think mentioning it would bring some extra value for your readers and give them a wider view of Python.

    As a thankyou, I would be glad to share your page with our 31k Facebook/Twitter/Linkedin Followers.
    Or
    I am happy to do Cross-Promotion.

    Let me know your thoughts. Thanks.
    Regards,
    Vinay
    PS: I am a real person... here is a number to contact me +1 302 308 5151