質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

1066閲覧

配列形式で受け渡された値をデータセットの形に整形し直して散布図を表示させたい

Uka

総合スコア28

HTML5

HTML5 (Hyper Text Markup Language、バージョン 5)は、マークアップ言語であるHTMLの第5版です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

0クリップ

投稿2021/06/15 12:07

前提・実現したいこと

javascriptを使って散布図グラフをブラウザに表示させたいと考えています。websocket経由でレスポンスとして返ってくる値が配列形式になっていますが、このままでは散布図のデータセットに対応できないため、各配列を[{x:0.389, y:0.00172},{x:0.413, y:0.00182}…]のような形に整形し直してデータセットに入れることで散布図表示ができるのではないかと考えています。似たような例がないかサイトなども調べていますが、どのように整形すればよいかがわかりません。もしアドバイスいただけましたらありがたいです。どうぞよろしくお願いいたします。

発生している問題・エラーメッセージ

グラフのレイアウトは表示されますが、値のプロットがされません。また、表のセルには、配列のままま表示されてしまっています。

該当のソースコード(test.pyの内容のうち、htmlに値を受け渡す部分のみ抜粋)

datas={"result1": b1.tolist(), "result2": b2.tolist()} print(datas) ws.send(json.dumps(datas))

該当のソースコード(index.html)

<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>graph test</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.2/Chart.bundle.js"></script> </head> <style> --省略-- </style> <script type="text/javascript"> $(document).ready(function(){ $('form').submit(function(event){ var inputText=$(".textBox").map(function(index,el){ ws.send($(this).val()) console.log($(this).val()) return false; }); return false; }); }); var ws = new WebSocket("ws://localhost:5000/publish"); // 初期データ var data = [[], []]; var result_graph = []; //websocket経由で受け取ったデータをparseしてChart.jsのデータに渡す ws.onmessage = function (msg) { var obj = JSON.parse(msg.data); console.log(obj.result1, obj.result2); result_graph.push({x:obj.resulet1, y:obj.result2}); var ctx = document.getElementById('tension-chart').getContext('2d'); var myChart = new Chart(ctx, { type: 'scatter', data: { datasets: [ { label: "Result", data: result_graph, pointRadius: 5, pointBorderRadius: 5, borderColor: '#0000ff', //showLine: false, yAxisID: 'first-y-axis', } ] }, options: { title: { display: true, text: "グラフ" }, maintainAspectRatio: false, elements: { line: { tension: 0.5 //Smoothening (Curved) of data lines } }, scales: { xAxes: [{ type: 'linear', position: 'bottom', scaleLabel: { display: true, labelString: 'X', fontFamily: "Arial", }, ticks: { // min: 0.1, // max: 10, // userCallback: function(tick) { // var remain = tick / (Math.pow(10, Math.floor(Chart.helpers.log10(tick)))); // if (remain === 1 || remain === 2 || remain === 5) { // return tick.toString() + ''; // } // return ''; //}, } }], yAxes: [{ id: 'first-y-axis', type:'linear', position: 'left', scaleLabel: { // 軸ラベル display: true, // 表示の有無 labelString: 'Y', fontFamily: "Arial", }, ticks: { //min: 0, //max: 0.1, // userCallback: function(tick) { // var remain = tick / (Math.pow(10, Math.floor(Chart.helpers.log10(tick)))); // if (remain === 1) { // return tick.toString() + ''; // } // return ''; // }, } },] } }, }); var table = document.getElementById("dataTable"); var row = table.insertRow(1); //Add after headings var cell1 = row.insertCell(0); var cell2 = row.insertCell(1); cell1.innerHTML = obj.result1; cell2.innerHTML = obj.result2; }; </script> <body> <form method='POST' action='#'> <fieldset class="chart-container" > <legend>入力フォーム</legend> <div class="inline-text"><label for="input-sample">テキスト1: </label><input type="text" name='data2' id="Text2" class="textBox" size="7"><font size="-1"> m</font></div> <div class="inline-text"><label for="input-sample">テキスト2: </label><input type="text" name='data5' id="Text5" class="textBox" size="7"><font size="-1"> m</font></div> <div><input type='submit'></div> </fieldset> </form> <div> <div class="chart-container" position:relative; height:300px; width:100%;><canvas id="result-chart" width="300" height="300"></canvas></div> </div> </body> <table id="dataTable"> #省略 </table> </html>

出力情報

【test.pyのprint(datas)の出力結果】
{'result1': [0.38957665111816914, 0.38957665111816914, 0.4111984833266004,

4.7520251230977255, 4.7520251230977255, 4.84960545143659, 5.17464331043214, 5.424969596340151],
'result2': [0.0017283185840707965, 0.0017283185840707965, 0.0017097345132743363,

0.00019513274336283184, 0.00018584070796460176, 0.00015796460176991148, 0.00013938053097345133]}

【index.htmlのconsole.logの出力結果】
Array形式で、result1とresult2それぞれの要素が64個縦に表示されます。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

各配列を[{x:0.389, y:0.00172},{x:0.413, y:0.00182}…]のような形に整形し直してデータセットに入れることで散布図表示ができるのではないかと考えています。似たような例がないかサイトなども調べていますが、どのように整形すればよいかがわかりません。もしアドバイスいただけましたらありがたいです。どうぞよろしくお願いいたします。

要は、2つの配列があって、それを[{x:数値,y:数値}, ...]の形にすればいいんですね?

サーバーのpythonでやる方法と、クライアント(ブラウザ)上のjsでやる方があります。また、データの整形をするとき、普通に配列をループして作る方法と、配列のメソッド(配列の関数)を使ってやる方法があります。

個人的には配列のメソッドを上手くつかう方法が短く、読み易くなることが多いので、配列の方で説明します。

まずpythonでやる方法ですが、

python

1 zipped = zip(b1.tolist(), b2.tolist()) #2つのリストを[[数値0,数値1], .... ]のリストにする 2 datas=list(map(lambda d: {"x":d[0], "y":d[1]}, zipped) #mapを使って、[[数値0, 数値1],...]のリストを[{x:数値,y:数値}, ...]の形にする... 3 print(datas) 4 ws.send(json.dumps(datas))

という感じで、zipとmapを上手く使う方法があります。

また、jsのやり方を乗せておきます。

js

1 // result1がxの配列データ、result2がyの配列データだとします 2//Array.mapを使い、コールバックの第一引数がreulst1の要素、 3//第二引数がresult1の要素のインデックスになるので、 4//同じインデックスのresult2の要素を取り出して、プロットデータを作る。 5 const data = result1.map((x,i)=>({x, y:result2[i] }); 6

という感じで作れます。コメントの通りですが、jsにはpythonのzip関数みたいなものはありませんが、Array.prototype.mapを使って、こんな感じに書くことができます。

投稿2021/06/15 13:20

編集2021/06/15 19:14
nobkz

総合スコア320

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Uka

2021/06/15 14:32

>nobkzさん、 ご回答くださいましてありがとうございます。大変参考になります。さっそくPythonで実装する方法で試してみたのですが、ご教示いただいたコードそのままだと、lambdaのところでxとyに同じd[0]を指定しているので、出力結果もb2の同じ値がx,yに割り当てられてリスト化されてしまいます({'x':0.389576, 'y':0.389576},{'x':0.411198, 'y':0.411198}… というように)実際には、配列1の1個目の要素と、配列2の1個目の要素の組み合わせ({'x':0.389576, 'y':y:0.00172}…というように)の形にしたいので、試しにlambda d, e: {"x":d[0], "y":e[0]}, zippedと書き換えて動作確認してみましたが、エラーとなってしまいました。。もしよろしければご教示いただけますと幸いです。よろしくお願いいたします。
Uka

2021/06/15 15:30

失礼しました、lambda d: {"x":d[0], "y":d[1]}とすることで所望のデータを得ることができました。大変助かりました。ありがとうございました。
nobkz

2021/06/15 19:13

あ、これは私のミスですね大変失礼いたしました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問