• ベストアンサー

C#での散布図の書き方

C#での散布図の書き方 C#を使って 横軸をx座標、縦軸をy座標として散布図を書きたいのですが 良い方法はありますでしょうか?;; 困り果てております;; お願いします;;

質問者が選んだベストアンサー

  • ベストアンサー
  • hiropuri
  • ベストアンサー率55% (24/43)
回答No.2

質問がありましたので再度記述させて頂きます。 「paintイベント上に記述」とは、デザイナ上からPaintイベントを追加する、 という意味です。 もしくは、下記のように記述して Paint イベントハンドラを オーバーライドしてもOKかと思います。 protected override void OnPaint(PaintEventArgs pea) { Point[] pt = new Point[100]; // 座標を格納する変数 Random rnd = new Random(); //テスト用:乱数生成用です // ※テスト用にランダムな座標を格納 for (int i = 0; i < pt.Length; i++) { pt[i].X = rnd.Next(this.Width); pt[i].Y = rnd.Next(this.Height); } // ↓ここからが実際の処理 Graphics g = this.CreateGraphics(); Bitmap bm = new Bitmap(this.Width, this.Height); // 全ての座標について点を描画する for (int i = 0; i < pt.Length; i++) { bm.SetPixel(pt[i].X, pt[i].Y, Color.Red); } g.DrawImage(bm, new Point(0, 0)); } ※上記を適当に貼り付ければ、動きは見られると思います。 ですが、あくまでもサンプルなので「あやしいコードだ!」と思って下さい。 軽く動かす程度にとどめて、より良いプログラムを作られる事を願っております(^^

saclover
質問者

補足

補足説明有難うございます! 実行してみたところ薄い点が何個も現われました。。 このような感じで点の大きさをもっと大きくしたいと思います。 ですがついでにもうちょっと伺いたい事が・・ (1)クラスター分析を行っていまして、入力した座標をあのように点で表示できれば良いのですが、 座標入力ボタンを作って入力しているのでそのボタンを押したら点が現われるみたいな感じにしたいと思っております。その場合はどうすれば・・;; (2)さきほどのサンプルだとフォーム上?に点が現われましたが、あそこにはたくさんのボタンをつけているのであそこには表示したうないです; 他の場所に出すことは可能なのでしょうか? まだお聞きしたい事があったように思いますが、また思い出した時に聞かせて頂きたいです; 上記の点、宜しくお願い致します;;

その他の回答 (4)

  • hiropuri
  • ベストアンサー率55% (24/43)
回答No.5

(1)点が小さすぎる 今まで自分が提示してきた例では、実は2つの方法が あった事を思い返してもらえると助かります。 a)Bitmapオブジェクトを生成して、そこに描画。 次にコントロール(orフォーム)のGraphicsオブジェクトを 取得し、それにBitmapオブジェクトに渡す。結果、 コントロール上(orフォーム上)に点が描画される方法 Bitmap bm = new Bitmap(this.Width, this.Height); g.DrawImage(bm, new Point(0, 0)); ……という形 b)コントロール(orフォーム)のGraphicsオブジェクトを 取得して、そのまま簡単に描画する方法 Graphics g = pic01.CreateGraphics(); g.FillEllipse……という形 なぜ2種類提示したかというと、Graphicsオブジェクトには 「1pixelだけ描画する」メソッドが見当たらなかったからです。 1pixelだけ描画するには、Bitmapオブジェクトの SetPixe を 使うのが手っ取り早いかな~って、それだけ(^^; なので、b)の方が簡単です。Bitmapオブジェクトが不要なので。 点の描画には、 Graphicsオブジェクトの FillRectangle(矩形描画) や FillEllipse(円描画) 等が利用できます。描画サイズや色の指定も可能です。 (例) SolidBrush brs = new SolidBrush(Color.FromArgb(0x00, 0xff, 0x00)); // 緑 Graphics g = pic01.CreateGraphics(); int ptSize = 4; // 点のサイズ g.FillEllipse(brs, 0-(ptSize/2), 0-(ptSize/2), ptSize, ptSize); これで、原点(0,0)を中心とした直径4ピクセルの円が描画されます。 半径ぶんをマイナスしないと中心点がズレる事にご注意を。 (2)PCの座標系は左上原点です。数学の左下原点とは勝手が違う ように思えますが、実は大した問題ではありません。 例えば、高さが400のpictureBoxを想像して下さい。 数学座標(0, 0) → PC座標(0, 400) 数学座標(10, 100) → PC座標(10, 300) つまり、y座標をチョコっと計算してやるだけです。 PC座標y = コントロールの高さ - 数学座標y その他にも、この手の小細工的計算をする事で遊べます。 グラフの原点を決めたり、描画倍率を変えたりとか……。 x座標に10を加算すれば、グラフ描画位置が右に10移動します。 これって、原点の右移動ですよね。座標に2をかければ2倍の サイズで描画できそうです。落ち着いて考えれば、それだけ なのです(^^ ・int型へのキャストについて 例ではintを使いましたが、それは必須ではないです。 「FillEllipse が受け取れる型」なら何でもOK!です。 各メソッドはオーバーロードされている場合がほとんどなので、 自分が使いやすい物を選ぶべきです。FillEllipse の場合は FillEllipse(Brush brush, float x, float y, float width, float height); FillEllipse(Brush brush, int x, int y, int width, int height); 等がありますので、floatの方を使うのもアリです。 ただ物理的には、モニタはpixelで構成されている事を意識して 下さい。例えば「0.7pixel」と指定した場合、実際はどこに 描画されるのか……それはC#任せ?となります。 ・SetPixel について まずBitmapオブジェクトですが、名前の通り「幅と高さがある 画像」をイメージして下さい。SetPixelは「Bitmapオブジェクト上」 の指定座標に対して1pixelを描画します。 次に g.DrawImage(bm, new Point(0, 0)); ですが、これは Point pt = new Point(0, 0); g.DrawImage(bm, pt); と全く同じですね。つまり、 bm(Bitmapオブジェクト)に描い絵を、 g(Graphicsオブジェクト)の座標(0,0)を起点として描画してね という事になります。

saclover
質問者

補足

hiropuriさん 表示できました!! 目視できるようになり、点の大きさも大きくなりました! 本当にありがとうございました! 絶対に僕だけではできませんでした;; 知らない命令や概念も教えて頂いて本当に助かりました! 11月中旬に発表会があるのでそこで存分に披露させて頂きたいと思います! ほんと何か菓子折りでもお礼さしあげたい限りです;; また何かありましたらぜひお願い致します! ここってお友達機能とかってありましたっけ;;? あったらお友達になって欲しいです;;

  • hiropuri
  • ベストアンサー率55% (24/43)
回答No.4

なるほど、そうだったんですね。 開発環境を明示しておくと、より踏み込んだ回答が得られますよ(^^ C#なので、開発環境はおそらく「Visual Studio」でしょうか。 「開発環境」と「イベント駆動型」に馴染みが無い、という事でしょうか。 「Visual Studio」をご利用と仮定して、基本的な操作等を補足させて頂きます。 ●コントロールにイベントを追加する イベント駆動型というくらいなので、様々な「イベント」に対して 処理を書くイメージです。例えば「クリックした」とか「マウスが 動いた」等、色々なイベントが存在します。 例えば「フォーム」について。どのようなイベントが存在するのか 手っ取り早く確認するには、以下の手順でOKです。 1)デザイナ(フォームやボタンを配置する画面)を開いて、 表示されているフォームをクリック(選択状態にする) 2)すると、プロパティ画面に「デザイナで選択中のコントロール」 の詳細情報が表示される。つまり、フォームの情報ですね。 3)プロパティウィンドウという名前ですが、イベントについても 取り扱っています。プロパティウィンドウの上側にある、 カミナリみたいなマークを押すと、イベントの一覧になります。 4)ずら~っとイベント一覧が表示されます。が、全てを理解する 必要はありません。実際に必要になるイベントは多くないのです。 例えば、フォームがクリックされた時に何か処理したい場合は、 「Click」というイベントに着目します。そこをダブルクリック して下さい。それだけで自動的に、イベント処理用の空コードが 追加されます。 private void Form1_Click(object sender, EventArgs e) { } ↑こんな感じですね。フォームがClickされると、この処理に 飛んできます。ここに処理を書いておけばいいわけですね。 上記手順はフォームだけでなく、他のコントロールでも同様です。 こうして、処理したいイベントを追加していく事になります。 ●プロパティについて 「属性」というと難解ですが、つまり「そのオブジェクトの状態」 を保持している変数みたいなモノです。それは色であったり、 コントロールの幅や高さであったり。 テキストボックスを例に考えます。 デザイナでテキストボックスを配置した後、プロパティウィンドウを 見て下さい。様々なプロパティが表示されていると思います。 よく使うのは「Text」プロパティで、ここに、テキストボックスに 表示されている文字列が格納されています。つまり、ここを 参照すれば、ユーザが入力した文字列を取得できるという事です。 (例)string buf = textbox1.Text; // 表示中の文字列を取得する ●描画関係の話 基本的に、Graphicsオブジェクトを利用する事になります。 各コントロール毎にGraphicsオブジェクトを持っているんだなぁ、 くらいに考えて下さい。フォーム上に線を引きたければ、フォームの Graphicsオブジェクトを取得。そのGraphicsオブジェクトが、 各種の描画関係メソッドを持っています(FillEllipse など) (参考) Draw~ は塗りつぶし無しの描画関係メソッドです。 線を描画するので Pen オブジェクトが必要となります。 Fill~ は塗りつぶし有りの描画関係メソッドです。 塗りつぶすので Brush オブジェクトが必要となります。 ●いつ描画すればいいのか? 例えば「ボタンを押した時に描画する」でも構いませんが、 それだと「一度だけ描画して終わり」です。他ウィンドウの 裏に隠れた後に最前面にもってくると、描画したモノは全て 消えている……という状態に。 なので「描画が必要になった時に描画する」必要があります。 それが Paint イベントです。無効領域が発生したので描画が 必要だよ!という時に発生するイベントなので、描画関係は Paint イベント内に記述する事が多いかと思います。 前述した方法で、Paintイベントを追加すればOKですよね。 上記の情報で、 ・ユーザの様々なアクションに対応した処理を実施する ・ユーザの入力した座標(文字列)を取得する ・指定のコントロール上に点や線を描画する という事が可能です。ご希望の処理が実装できる……と、 思います、たぶん(^^; 判り難い点も多々あると思いますが。 経験者という事で、アルゴリズム的な話は無くてもOKと 思います。後は慣れの問題だけですので、頑張って下さい!

saclover
質問者

補足

本当に詳しいご説明有難う御座います;; かなり助けられております;; 本当に素晴らしい的確なご説明素晴らしい限りです;; 感謝でいっぱいです; あれから参考にさせて頂いて自分で進めた結果 pictureBoXをクリックすると何かしらの点が現われるようになりました; 一応これらの点は入力したx、y座標の散布図のようなものを期待しているのですが 問題がありまして・・ (1)点が小さすぎる・・ 小さすぎて確認できません;; この点のサイズを変更と蚊はできるのでしょうか? (2)座標軸の原点がどうやら左上にあるようですね;; これを正常な右上がりグラフにするにはどうすれば・・;; ちなみにpictureBoxの今現在のソースを添付しておきます; private void pictureBox1_Click(object sender, EventArgs e) { Point[] pt = new Point[100]; // 座標を格納する変数 for (int i = 0; i < kosu_i; i++) { pt[i].X = (int)data_d[i, 0]; pt[i].Y = (int)data_d[i, 1]; } // ↓ここからが実際の処理 pictureBox1.Refresh(); // 念の為、描画した点を消去する Graphics g = pictureBox1.CreateGraphics(); Bitmap bm = new Bitmap(pictureBox1.Width, pictureBox1.Height); // 全ての座標について点を描画する for (int i = 0; i < kosu_i; i++) { bm.SetPixel(pt[i].X, pt[i].Y, Color.Red); } g.DrawImage(bm, new Point(0, 0)); } data_d[ , ]は2次元配列となっていて [0,0]:データ0のx座標 [0,1]:データ0のy座標 をあらわしております; ちなみにdata_dはdouble型なのでint型のpt[]に代入する際にintにキャストしているという問題が生じております; あと確認させて頂きたいことがあるのですが SetPixeは指定したpt[i].X, pt[i].に色を配置するという意味で DrawImageでbmを指定することによりSetPixelで格納したピクセルに色を描画する という意味でよろしいのですよね? その際DrawImageで指定しているnew Point(0,0)はどういうことなのでしょうか;; ご質問ばかり本当に申し訳ありません;><

  • hiropuri
  • ベストアンサー率55% (24/43)
回答No.3

またまた失礼します。ご質問を頂いたので……。 先ほどのソースコードは、フォーム自体に描画していました。 例えば、ピクチャーボックスを配置して、そこの中に描画したい! という場合でも、ちょっとした応用で実現可能です。 // ※pic01はピクチャーボックスの名前です pic01.Refresh(); // 念の為、描画した点を消去する int ptSize = 8; // 描画する点の直径 Graphics g = pic01.CreateGraphics(); SolidBrush brs = new SolidBrush(Color.Red); for (int i = 0; i < pt.Length; i++) { g.FillEllipse(brs, pt[i].X - ptSize / 2, pt[i].Y - ptSize / 2, ptSize, ptSize); } brs.Dispose(); //brushオブジェクトの解放 FillEllipse は「塗りつぶした円」を描画するメソッドです。 お話していて感じたのですが、C#、もしくはプログラミングは 初めてでしょうか? 現状ですと、処理を実装していくには、 ほんの僅かに基礎が不足しているように感じるのです。 1)フォーム上に以下のオブジェクトを配置(デザイナにて) ・点を描画する為のコントロール(PictureBoxなど) ・ユーザが座標を入力をする為のTextBoxを2つ(x,y) ・描画実行!みたいなButton 2)ButtonにClickイベントを追加 3)ButtonでClickイベント内に、 ・TextBoxに入力されている文字を取得して ・それを数値に変換する ・座標として変数に格納する 4)格納されている座標を参照して、PictureBoxに点を描画する という雰囲気になると思います。もし、上記の中でイメージが 全く沸かない、どう記述したらいいか判らないといった処理が あるとしたら、この先を作り続ける事は非常に困難だと思うのです。 どうか遠回りとは思わずに、もう少し基本的な部分を……例えば、 イベントやメソッドについてweb等で調べつつ、色々とお試しに なる事をおすすめしたいです。苦手意識を持つ必要はありません、 C#は決して難しくないので大丈夫ですよ(^^ ・イベント ・プロパティ ・メソッド これらのキーワードを足がかりにするといいかもしれません。

saclover
質問者

補足

ホントにご丁寧にありがとうございます;; 高専生なのでプログラミングは4年間ほどやっておりますよ^^ ですがこれまでC中心だったのとjavaを1年ほどかじっただけで C#はあまり詳しく知りませんでした;; 特にイベントのあたりがよく分からなくて;; 教えて頂いて参考にしたいと思います; ありがとうございました!

  • hiropuri
  • ベストアンサー率55% (24/43)
回答No.1

C#にて「点を描画したい」という事でよろしいでしょうか? 例えば、フォーム上に直接「指定した点」を描画する場合を考えます。 次のコードを、フォームのPaintイベントに記述すればOKかと思います。 Graphics g = this.CreateGraphics(); Bitmap bm = new Bitmap(this.Width, this.Height); for (int i = 0; i < pt.Length; i++) { // ※pt[] はPoint型の配列で、既にデータが入っているものとします bm.SetPixel(pt[i].X, pt[i].Y, Color.Red); } g.DrawImage(bm, new Point(0, 0)); こんな感じになるかと思うのですが、どうでしょうか?

saclover
質問者

補足

ご回答有難うございます! やってみたいのですが・・ paintイベント上に記述とは・・;どうすればいのでしょうか? あまり詳しくないもので;; 教えて頂けると助かります;;

関連するQ&A

  • Excel2007の散布図についてですが...

    Excel2007の散布図についてですが... 何分2007に慣れておりません。1行目に数字がAからIまで並び、5行目にそれに対応する結果が同じくAからIまで並んでいた場合ですが、[挿入]を選択するとグラフの部分の選択が出てきて散布図を選ぶと散布図がかけます。ところでこれが1行目が横軸、5行目が縦軸の散布図となります。1行目を縦軸に、5行目を横軸にするグラフに入れ替えたいのですができません。こんな簡単なはずの操作で困っております。ご教授下さい。

  • エクセルの散布図の作成で…

    エクセルの散布図の作成で… こんにちは。エクセルの散布図の作成で、 横軸が同じ二つのデータを、二種類の縦軸をつかって一つの 散布図に表したいです。 図の縦軸Aを左側に、縦軸Bを右側に表して、一つの図にまとめ たいのです。 ソフトはマイクロソフトオフィス2007です。 作成方法、あるいはそれが乗っているサイトなどご紹介いただける とたすかります。よろしくお願いいたします。

  • エクセル2007の散布図について

    エクセル2007で作る散布図について、縦軸、横軸に名前をつけたり、グラフタイトルをつけたりしたいのですが、どうすればいいでしょうか?

  • Excel 2010での散布図の作成方法

    Excel 2010で相関を見る散布図を作りたいのですが、うまくいきません。 こちらのサイトで例に出ているような、横軸が系列1で縦軸が系列2の散布図を作りたいのですが、 http://hitorimarketing.net/tools/correlation-analysis.html サイトに書かれている、縦2列のデータを見出しを除き選択→挿入タブの散布図をクリック という方法では、2系列のデータなのに1系列の(横軸がデータ数・縦軸が数値の)散布図になってしまいます。 Excelに詳しい方、教えてください。

  • EXCELの散布図 エクセル

    みなさんこんにちは。 エクセルのグラフ機能(散布図)を使ってX、Y座標値を展開してます。 1番 X=2 Y=2  2番 X=1 Y=2 3番 X=1 Y=1 4番 X=2 Y=1 ちゃんと作図はできるのですが、図には頂点番号が表示されず、どの頂点が表中のどの番号なのかがわかりません(カーソルを図中の頂点にあわせて表示されるX、Y数値の一致で知り得ています。面倒です)。 教えてほしいことは、この図に頂点番号を表示させることは可能でしょうか? 可能でしたらその方法を教えてください。

  • EXCELの散布図について教えてください

    こんにちは。 EXCELの散布図で、指定のX・Y座標にマーカーを表示し、 ラベルとして座標値でも系列名でもない任意の文字列(実際は社名)を 表示したいのですが、こういったことは簡単に出来るものなのでしょうか? データは3種類あり 1)社名 2)数値 3)数値 2)と3)の交わる部分に1)の社名を示して欲しいということでした。 「二軸散布図」を調べれば良いと言われたものの、 私の乏しい知識ではいくら読んでも理解し辛く、質問させていただきました。 よろしくお願いいたします。

  • エクセルの散布図

    ラベル付きの散布図を作成したいのですが、ちょっとやりかたがわからなくて、困っています。 要するに データ名  x座標   y座標 ----------------------------- データ1  1.55345  -2.10188 データ2  0.93827  -0.37629 データ3  0.73248  -1.28221 データ4  -0.73542  -0.92798 データ5  1.88498  -1.54822 データ6  1.88733  -2.28795 データ7  0.50953  -0.5687 で、x, y座標の点の横あたりにデータ名も表示させたいのです。 エクセルのところで質問させてもらいましたが、上記の事ができればソフトはエクセルでなくてもかまいません。 どなたかご教授をよろしくお願いします。

  • 散布図を縦に2個並べて出力したい

    Excelを使い始めたばかりなのですが、使い方がわからず困っているため質問させていただきます。 例として以下のようなデータがあるときに x y_1 y_2 1 3 9 2 7 2 3 2 3 4 8 6 5 3 1 xの値を横軸にとって縦軸にy_1とy_2の値を取ると 1つのグラフに2つの系列のグラフができると思うんですが、これを1つの系列ごとにグラフにして出したいです。 横軸は揃えて、縦軸は10~0を2回繰り返すようなグラフです。 説明がわかりにくいかもしれませんが、このようなグラフの作り方を教えていただきたいです。 よろしくお願いします。

  • EXCELでの散布図の作成方法

    EXCELで散布図を作成したいのですが, どうやってつくって良いかよくわかりません... いくつかの群の体重を比較したいと思っています. そこで,横軸はそれぞれの群ごとに分けて,縦軸を体重として 1つのグラフとして作成したいです. しかし,1つの群しかグラフに乗せることができず,またその群も横軸が 1,2,3,・・・・のように横に広がったグラフになってしまいます. このような広がることがなく作成することができる方法を教えてください. 宜しくお願いします.

  • excelの散布図

    散布図を使ってグラフを作成するにいたって、初歩的なことかもしれませんがどうしてもわからないことがあります。 横軸に時間、縦軸に移動距離をとるとします。 例えば横軸に20分、40分...100分と 20分毎のデータをプロットします。 その時、横軸の最小値を0分ではなく、例えば15分にする必要があるとします。 そこで、 (A) 横軸の最小値を15分にしてしまうと、軸目盛りの表示が15分、35分...115分のように表示されてしまい、20分、40分...100分という表示ではなくなります。 また、 (B) 縦軸との交点を15分にすることで、横軸目盛りの20分、40分...100分という表示は維持できますが、その場合0分から15分の部分が縦軸に対して左側にあり、不恰好です。 これを解決したいのですが、どうかよろしくお願いします。 ペイントで作成した理想的な画像を添付しておきます。

専門家に質問してみよう