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

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

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

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

gnuplot

gnuplot(ニュープロット)は、2次元や3次元のグラフ作成ができるソフトウェアです。さまざまな数式やデータ集計などのグラフを描写することが可能で、特に2次元グラフを描画する機能は強力です。

Q&A

1回答

9551閲覧

c言語とgnuplotを用いてヒストグラムを作成する

yukatii

総合スコア5

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

gnuplot

gnuplot(ニュープロット)は、2次元や3次元のグラフ作成ができるソフトウェアです。さまざまな数式やデータ集計などのグラフを描写することが可能で、特に2次元グラフを描画する機能は強力です。

0グッド

1クリップ

投稿2020/06/17 15:24

編集2020/06/18 02:47

前提・実現したいこと

c言語とgnuplotで、1クラス分の生徒の個々の平均点をヒストグラムにするプログラムを作成中です。(グラフの横軸が10点ごとの点数、縦軸が人数)
生徒1人1人の平均点を出すところまではいけたのですが、グラフ化するところで苦戦しています。

簡単なフローチャート

平均点010、1120、2130のように変数を10個つくる
→一人の平均点が56点だった
→51
60の変数+1
→人数分繰り返し。

###試したこと
いろんなサイトで調べて、配列をgnuplotに渡すやり方はわかったのですが、縦軸を人数で表記するというやり方がどこにも載っていなかったので、考え方などを教えてくださるとうれしいです。
よろしくお願いします。

###ソースコード
平均を計算するプログラムとグラフ化するプログラムを一旦分けているので、グラフ化の方だけ記述します。

#include <stdio.h> int main(void) { FILE *gp; //パイプを開く int i; int x[10]; for(i=0;i<10;i++){ x[i]=i*10; } gp=_popen("gnuplot -persist","w"); //gnuplot起動。-persistでずっと開いた状態にする fprintf(gp,"set boxwidth 1\n"); //棒グラフの設定,棒の太さ fprintf(gp, "set xrange [0:10]\n"); //x軸の表示設定 fprintf(gp, "set yrange [0:100]\n"); //y軸の表示設定 fprintf(gp,"plot '-' with boxes\n"); for(i=0;i<10;i++){ fprintf(gp,"%d\t%d\n",i,x[i]); } fprintf(gp,"e\n"); fflush(gp); _pclose(gp); return 0; }

このプログラムに、

if(x[i]<=10) hist0+=1; else if(11<=x[i]<=20) hist1+=1; else if(21<=x[i]<=30) hist2+=1; else if(31<=x[i]<=40) hist3+=1; else if(41<=x[i]<=50) hist4+=1; else if(51<=x[i]<=60) hist5+=1; else if(61<=x[i]<=70) hist6+=1; else if(71<=x[i]<=80) hist7+=1; else if(81<=x[i]<=90) hist8+=1; else if(91<=x[i]<=100) hist9+=1;

を追加したいと思っています。
#出力結果
イメージ説明

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

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

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

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

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

hope_mucci

2020/06/18 01:10

・作成したコードと、現在のコードで出力されるデータを本文に追記しましょう。そうすると回答者が現状の問題点を把握しやすくなります。コードの挿入方法は以下ヘルプをよく読んで<code>ボタンで挿入しましょう。プレビューもちゃんと確認すること。 https://teratail.com/help/question-tips#questionTips3-5
guest

回答1

0

どの点が疑問なのかちょっと分かっていないかもしれません。

提示ソースコードで、とりあえずの値を格納している部分を、

C

1for(i=0;i<10;i++){ 2 x[i]=i*10; 3}

質問で提示されている処理内容で置き換えれば良いのではないでしょうか?

平均点010、1120、2130のように変数を10個つくる
→一人の平均点が56点だった
→51
60の変数+1
→人数分繰り返し。

人数分の平均値が配列avg[]に入ってるとして、グラフのヒストグラム値を配列x[]へ振り分けていくような処理になると思います。

C

1for ( i = 0 ; i < person_count ; ++ i ) { 2 if( avg[i]<=10) { 3  x[0] += 1; 4 } 5 else if( avg[i]<=20) { 6  x[1] += 1; 7 } 8 else if( avg[i]<=30) { 9  x[2] += 1; 10 } 11 else if( avg[i]<=40) { 12  x[3] += 1; 13 } 14 else if( avg[i]<=50) { 15  x[4] += 1; 16 } 17 else if( avg[i]<=60) { 18  x[5] += 1; 19 } 20 else if( avg[i]<=70) { 21  x[6] += 1; 22 } 23 else if( avg[i]<=80) { 24  x[7] += 1; 25 } 26 else if( avg[i]<=90) { 27  x[8] += 1; 28 } 29 else /* if( avg[i]<=100) */ { 30  x[9] += 1; 31 } 32}

上記ソースコードは質問での提示コードに合わせてやや冗長に書きましたが、
平均点の境界に注意すれば次のような感じに短く書けると思います。

C

1for ( i = 0 ; i < person_count ; ++ i ) { 2 if ( avg[ i ] <= 100 ) { 3 x[ (int)( avg[ i ] / 10 ) ] += 1; 4 } 5 else { 6 x[ 9 ] += 1; 7 } 8}

あと1点、gnuplotは表示範囲を明示的に指定しなくてもグラフが表示領域に収まるように調整してくれると思いますが、明示的にスケールを指定するつもりなら配列x[]の中身を見てちゃんと設定するように以下の箇所を修正する必要があると思います。

C

1fprintf(gp, "set yrange [0:100]\n"); //y軸の表示設定

投稿2020/06/18 04:47

hidezzz

総合スコア1248

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問