LoginSignup
0
0

【jsPsych】行動実験でグラフを提示してみよう

Posted at

はじめに

  • 5年ほど前に以下のような質問が黒木先生宛にきていました。

  • どうやら, jsPsychでの実験中にpie chartといったグラフを提示しようという試みのようです。今更感はありますが,今回はサンプルコードを書いてみました。

  • webブラウザ上でグラフを提示するにはchart.jsライブラリというものが簡便かつ美しく表示できるので,こちらを利用します。

  • chart.jsを使用するには<canvas>タグを利用する必要があります。jsPsychでは<canvas>を利用する際にはcanvas-button-responseやcanvas-keyboard-responseといったプラグインを用いるのが有用ですので,その利用方法について簡単にまとめます。

chart.js

  • chart.jsはJavaScriptでグラフ(chart)を表示するためのライブラリです(https://www.tohoho-web.com/ex/chartjs.html)

  • 単純な棒グラフや線グラフだけでなく,多くの形式でグラフを作成することができます。

  • htmlで段落を示すには<p>タグを用い,画像を提示するには<img>タグを用いるのと同様に,四角や円といった図形を表示するには<canvas>タグを利用します。

  • <canvas>タグは単純な図形を表示するだけなら簡単ですが,複雑な図形を描くのはかなり大変です。

  • グラフを<canvas>上で簡単に書けるようにしたライブラリがchart.jsです。

  • 利用するためには,jsPsychでプラグインを事前に読み込むのと同様に,chart.jsライブラリを読み込んでおく必要があります。オンラインであれば,以下のようにして読み込みます。

<script src="https://unpkg.com/@jspsych/plugin-html-button-response@1.1.2"></script>
<script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script> // こいつがchart.jsの読み込み
<script src="https://unpkg.com/@jspsych/plugin-canvas-button-response@1.1.2"></script>

jsPsychにおける<canvas>

公式サイトのデモ

  • canvas-button-responseプラグインの使用方法は公式サイトにデモがあります。以下のようなコードを書きます。
function filledCirc(canvas, radius, color) {
    var ctx = canvas.getContext("2d");
    ctx.beginPath();
    ctx.arc(150, 150, radius, 0, 2 * Math.PI);
    ctx.fillStyle = color;
    ctx.fill();
}

var circle_1 = {
    type: jsPsychCanvasButtonResponse,
    stimulus: function(c) {
        filledCirc(c, 100, 'blue');
    },
    canvas_size: [300, 300],
    choices: ['Red', 'Green', 'Blue'],
    prompt: '<p>What color is the circle?</p>',
    data: {color: 'blue', radius: 100}
};
  • このプラグインでは,図形を描くfunctionを事前に作成し(filledCirc),それをcanvas-button-responseで表示するという流れになります。
  • この事前に作成するfunctionでグラフに関する命令を書きます(chart.js)

サンプルコード

  • 今回は実験課題中のFキーとJキーを押した回数とそれぞれの平均反応時間をグラフ化してみます。

    • キー押し回数は円グラフ,反応時間は棒グラフで描画します。
  • 例えば,pie chartを表示するには,以下のようなコードを書きます。

function piechart(c, F, J) {
        var ctx = c.getContext("2d");
        let pieConfig = {
          type: 'pie',
          data: {
            labels: ['Fkey','Jkey'],
            datasets: [{
              label: 'キー押し回数',
              data: [F, J], ///F, Jにはそれぞれ,課題中にFキー,Jキーを押した回数が格納されています
              backgroundColor: [
                '#ff0000',
                '#0000ff',
              ]
            }]
          },
        };
        let pieChart = new Chart(ctx, pieConfig);
    }
  • このtypeの部分をbarに変えれば,棒グラフになります。

    • chart.jsの基本的な書き方は日本語でも多くの記事があるので,参考サイトには困らないと思います。
  • どのようなデータを用いるのかはjsPsych APIでデータを抽出し,計算すれば良いです。

Demoとコード

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="UTF-8">
    <title>My experiment</title>
    <script src="https://unpkg.com/jspsych@7.3.3"></script>
    <link href="https://unpkg.com/jspsych@7.3.3/css/jspsych.css" rel="stylesheet" type="text/css" />
    <script src="https://unpkg.com/@jspsych/plugin-html-keyboard-response@1.1.2"></script>
    <script src="https://unpkg.com/@jspsych/plugin-html-button-response@1.1.2"></script>
    <script src="https://cdn.jsdelivr.net/npm/chart.js@3.9.1/dist/chart.min.js"></script>
    <script src="https://unpkg.com/@jspsych/plugin-canvas-button-response@1.1.2"></script>


</head>

<body></body>
<script>
    /* initialize jsPsych */
    const jsPsych = initJsPsych({
        on_finish: function () {
            jsPsych.data.displayData();
        }
    });

    const timeline = [];

    const ins = {
        type: jsPsychHtmlButtonResponse,
        stimulus: '<p>Demoを始める。</p>',
        choices: ['Start']
    };

    const fix = {
        type: jsPsychHtmlKeyboardResponse,
        stimulus: '',
        choices: "NO_KEYS",
        trial_duration: 1000
    }
    
    const trial = {
        type: jsPsychHtmlKeyboardResponse,
        stimulus: "<p>FかJのどちらかを入力してください。</p>",
        choices: ["f", "j"],
        data: {
            task: 'response'
        },
        on_finish: function (data) {
            data.Fkey = jsPsych.pluginAPI.compareKeys(data.response, 'F');
            data.Jkey = jsPsych.pluginAPI.compareKeys(data.response, 'J');
        }

    };




    const procedures = {
        timeline: [fix, trial],
        repetitions: 10,
        on_finish: function () {
            trials = jsPsych.data.get().filter({ task: 'response' });
            Fkey_trials = trials.filter({ Fkey: true });
            Jkey_trials = trials.filter({ Jkey: true });
            FkeyCount = Fkey_trials.count();
            JkeyCount = Jkey_trials.count();
            Frt = Math.round(Fkey_trials.select('rt').mean());
            Jrt = Math.round(Jkey_trials.select('rt').mean());
        }
    };

    function piechart(c, F, J) {
        var ctx = c.getContext("2d");
        let pieConfig = {
          type: 'pie',
          data: {
            labels: ['Fkey','Jkey'],
            datasets: [{
              label: 'キー押し回数',
              data: [F, J],
              backgroundColor: [
                '#ff0000',
                '#0000ff',
              ]
            }]
          },
        };
        let pieChart = new Chart(ctx, pieConfig);
    }

    function barchart(c, F, J) {
        var ctx = c.getContext("2d");
        let barConfig = {
          type: 'bar',
          data: {
            labels: ['Fkey','Jkey'],
            datasets: [{
              label: '平均反応時間(ms)',
              data: [Frt, Jrt],
              backgroundColor: [
                '#ff0000',
                '#0000ff',
              ]
            }]
          },
        };
        let barChart = new Chart(ctx, barConfig);
    }

    var chart1 = {
        type: jsPsychCanvasButtonResponse,
        stimulus: function(c) {
            piechart(c, FkeyCount, JkeyCount)
        },
        canvas_size: [500, 500],
        choices: ['棒グラフに進む'],
        prompt: '<p>キー押し回数のpie chartはこんな感じ</p>'
    };

    var chart2 = {
        type: jsPsychCanvasButtonResponse,
        stimulus: function(c) {
            barchart(c, Frt, Jrt)
        },
        canvas_size: [500, 500],
        choices: ['終了する'],
        prompt: '<p>それぞれのキー押しの平均反応時間はこんな感じ</p>'
    };



    timeline.push(ins, procedures, chart1, chart2);
    jsPsych.run(timeline);

</script>


</html>
  • いつかもう少し丁寧に書くかもしれません。
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0