C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: 対数グラフをリニアに戻すとエラーとなる


(過去ログ 164 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■94971 / inTopicNo.1)  対数グラフをリニアに戻すとエラーとなる
  
□投稿者/ 還暦おやじkuma (1回)-(2020/06/07(Sun) 22:06:20)

分類:[C#] 

C#を始めて3年目の初心者(還暦おやじkuma)です。長文すみません。

**環境:Windows10 ver.1909, Intel Core i5, RAM 8GB,x64,
Visual Studio Express 2013 for Windows Desktop, C# 5.0, NetFramework 4.5
(Community2017,2019系は会社の都合で入れることができませんので古い環境でやっています)

**疑問点:アプリを実行してChartType=Lineでリニアグラフが描かれ、チェックボックスでX軸を対数表示にすることまではできますが、もう1度チェックボックスをクリックしてグラフを再描画してリニアに戻そうとするとエラーとなります。描画ルーチンのtry-catchでは引っ掛かりません。
原因と解決方法がお分かりでしたらご教示いただけますでしょうか?。

**補足:
・デザイナーではlog_checkBoxという名前のCheckBoxを1つ追加してあるだけで、他はデフォルトのままです。

・X軸のデータmydataXの[0]に意図的に0.00を入れてありますが、対数グラフを描画する際には飛ばすようにしています。もっとも、元データの0.00を1.10とかにしても結果は同じエラーとなりますが。

**エラーメッセージ:
「追加情報:軸オブジェクト - 対数グラフでは、負の値または 0 を正しくプロットできません。対数スケールで解釈できるのは正の値だけです。」
と出ますが、もともと負の値は無く、0も回避するようにしているのと、1度目は対数で描画できているので、意味が分かりません。

・dobon.netさんの「捕捉されなかった例外がスローされたことを知る」
http://dobon.net/vb/dotnet/programing/unhandledexception.html
を参考に、MainにThreadExceptionイベントハンドラを入れてみましたが、
Message = 軸オブジェクト - 対数グラフでは、負の値または 0 を正しくプロットできません。対数スケールで解釈できるのは正の値だけです。
パラメーター名:minimumValue
Source = System.Windows.Forms.DataVisualization
TypeName = ArgumentOutOfRangeException
StackTrace =    場所 System.Windows.Forms.DataVisualization.Charting.Axis.EstimateLogarithmicAxis(Double& minimumValue, Double& maximumValue, Double crossingValue, Boolean autoMaximum, Boolean autoMinimum)
 以下、場所がずらずらと。
と出るため、私には原因が分かりませんでした。

パラメーター名:minimumValueは
「this.chart1.ChartAreas[0].AxisX.Minimum = 1.0;//対数表示にはこれが必要」
としてあるのですが、どうもこれのことではないような・・・。

= = = = = = = = = = = = Form1ソース= = = = = = = = = = = = = = = = 
using はデフォルトのままなので省略
namespace LogGraphTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //以下は、もともとは別のクラスで読み込むデータだが質問のサンプルとしてここに書いているだけ。
        static public double[] mydataX = new double[] { 0.00, 3.02, 3.91, 32.66, 141.51, 251.45, 461.08, 771.34, 801.49, 911.34, 1000.00 };//意図的に[0]に0を入れてある。
        static public double[] mydataY1 = new double[] { 102.14, 92.08, 53.44, 46.56, 78.27, 49.20, 103.60, 48.33, 29.83, 71.15, 7.22 };

        drawGraph form_graph = new drawGraph();//もともとは別のクラスからも呼び出しているがサンプルとしてここにこう書いているだけ。


        private void Form1_Load(object sender, EventArgs e)
        {
            form_graph.Left = this.Right;
            form_graph.Top = this.Top;
            form_graph.StartPosition = FormStartPosition.Manual;
            form_graph.Show();

        }
    }
}
= = = = = = = = = = = = drawGraphソース= = = = = = = = = = = = = = = = 
using はデフォルトのものは省略
using System.Windows.Forms.DataVisualization.Charting;//追加した
using System.Diagnostics;//try-catchの結果を出力に出すために追加した

namespace LogGraphTest
{
    public partial class drawGraph : Form
    {
        public drawGraph()
        {
            InitializeComponent();
        }

        static bool isGraphLog = false;//テスト用に初期値を入れ替えるためにここに記載

        private void drawGraph_Load(object sender, EventArgs e)
        {
            chart1.ChartAreas[0].CursorX.IsUserEnabled = true;
            chart1.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
            chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = true;

            drawDataGraph();
            log_checkBox.Checked = isGraphLog;
        }

        public void drawDataGraph()
        {
            try
            {
                chart1.Series.Clear();//log_checkBoxをクリックしたときにdrawDataGraph()を再描画するために過去のSeriesをクリアする
                if (isGraphLog)
                {
                    this.chart1.ChartAreas[0].AxisX.Minimum = 1.0;//対数表示にはこれが必要
                }
                else
                {
                    this.chart1.ChartAreas[0].AxisX.Minimum = 0.0;//リニア表示にはこれが必要
                }

                if (isGraphLog)
                {
                    chart1.ChartAreas[0].AxisX.IsStartedFromZero = false;//対数表示にはこれが必要か?、データも0を含んでいてはいけないが
                    chart1.ChartAreas[0].AxisX.IsLogarithmic = true;
                }

                Series[] dseries = new Series[2];//もともと複数のデータ系列があったため配列として[2]としてあるが、このサンプルでは1つなので意味は無い。
                dseries[0] = new Series();
                dseries[0].ChartType = SeriesChartType.Line;
                dseries[0].Name = "DataY1";
                dseries[0].Color = Color.Black;
                this.chart1.Series.Add(dseries[0]);

                int startData = 0;
                if (isGraphLog) { startData = 1; }//Logの時はデータがx=0である[0]を飛ばしている。このためLogのグラフが描ける、のでは?
                for (int i = startData; i < 11; i++)
                {
                    chart1.Series[dseries[0].Name].Points.AddXY(Form1.mydataX[i], Form1.mydataY1[i]);
                }
            }
            catch (System.Exception ex)
            {
                Debug.WriteLine("Message = " + ex.Message);
                Debug.WriteLine("Source = " + ex.Source);
                Debug.WriteLine("StackTrace = " + ex.StackTrace);
                throw;//例外を再スローする
            }
        }

        private void log_checkBox_CheckedChanged(object sender, EventArgs e)
        {
            if (log_checkBox.Checked)// isGraphLog = log_checkBox.Checkedとも書けると思うが念のために細かく書いた。
            {
                isGraphLog = true;
            }
            else
            {
                isGraphLog = false;
            }
            drawDataGraph();
        }
    }
}
= = = = = = = = = = = = ソースはここまで= = = = = = = = = = = = = = = = 
すみませんが、ご教示よろしくお願いいたします。

引用返信 編集キー/
■94972 / inTopicNo.2)  Re[1]: 対数グラフをリニアに戻すとエラーとなる
□投稿者/ 還暦おやじkuma (2回)-(2020/06/07(Sun) 22:40:13)
No94971 (還暦おやじkuma さん) に返信
> C#を始めて3年目の初心者(還暦おやじkuma)です。長文すみません。
> 
> **環境:Windows10 ver.1909, Intel Core i5, RAM 8GB,x64,
> Visual Studio Express 2013 for Windows Desktop, C# 5.0, NetFramework 4.5
> (Community2017,2019系は会社の都合で入れることができませんので古い環境でやっています)
> 
> **疑問点:アプリを実行してChartType=Lineでリニアグラフが描かれ、チェックボックスでX軸を対数表示にすることまではできますが、もう1度チェックボックスをクリックしてグラフを再描画してリニアに戻そうとするとエラーとなります。描画ルーチンのtry-catchでは引っ掛かりません。
> 原因と解決方法がお分かりでしたらご教示いただけますでしょうか?。
> 
> **補足:
> ・デザイナーではlog_checkBoxという名前のCheckBoxを1つ追加してあるだけで、他はデフォルトのままです。
追記 すみません、もちろんChartもdrawGraph側に1つ入れています。
> 
> ・X軸のデータmydataXの[0]に意図的に0.00を入れてありますが、対数グラフを描画する際には飛ばすようにしています。もっとも、元データの0.00を1.10とかにしても結果は同じエラーとなりますが。
> 
> **エラーメッセージ:
> 「追加情報:軸オブジェクト - 対数グラフでは、負の値または 0 を正しくプロットできません。対数スケールで解釈できるのは正の値だけです。」
> と出ますが、もともと負の値は無く、0も回避するようにしているのと、1度目は対数で描画できているので、意味が分かりません。
> 
> ・dobon.netさんの「捕捉されなかった例外がスローされたことを知る」
> http://dobon.net/vb/dotnet/programing/unhandledexception.html
> を参考に、MainにThreadExceptionイベントハンドラを入れてみましたが、
> Message = 軸オブジェクト - 対数グラフでは、負の値または 0 を正しくプロットできません。対数スケールで解釈できるのは正の値だけです。
> パラメーター名:minimumValue
> Source = System.Windows.Forms.DataVisualization
> TypeName = ArgumentOutOfRangeException
> StackTrace =    場所 System.Windows.Forms.DataVisualization.Charting.Axis.EstimateLogarithmicAxis(Double& minimumValue, Double& maximumValue, Double crossingValue, Boolean autoMaximum, Boolean autoMinimum)
>  以下、場所がずらずらと。
> と出るため、私には原因が分かりませんでした。
> 
> パラメーター名:minimumValueは
> 「this.chart1.ChartAreas[0].AxisX.Minimum = 1.0;//対数表示にはこれが必要」
> としてあるのですが、どうもこれのことではないような・・・。
> 
> = = = = = = = = = = = = Form1ソース= = = = = = = = = = = = = = = = 
> using はデフォルトのままなので省略
> namespace LogGraphTest
> {
>     public partial class Form1 : Form
>     {
>         public Form1()
>         {
>             InitializeComponent();
>         }
>         //以下は、もともとは別のクラスで読み込むデータだが質問のサンプルとしてここに書いているだけ。
>         static public double[] mydataX = new double[] { 0.00, 3.02, 3.91, 32.66, 141.51, 251.45, 461.08, 771.34, 801.49, 911.34, 1000.00 };//意図的に[0]に0を入れてある。
>         static public double[] mydataY1 = new double[] { 102.14, 92.08, 53.44, 46.56, 78.27, 49.20, 103.60, 48.33, 29.83, 71.15, 7.22 };
> 
>         drawGraph form_graph = new drawGraph();//もともとは別のクラスからも呼び出しているがサンプルとしてここにこう書いているだけ。
> 
> 
>         private void Form1_Load(object sender, EventArgs e)
>         {
>             form_graph.Left = this.Right;
>             form_graph.Top = this.Top;
>             form_graph.StartPosition = FormStartPosition.Manual;
>             form_graph.Show();
> 
>         }
>     }
> }
> = = = = = = = = = = = = drawGraphソース= = = = = = = = = = = = = = = = 
> using はデフォルトのものは省略
> using System.Windows.Forms.DataVisualization.Charting;//追加した
> using System.Diagnostics;//try-catchの結果を出力に出すために追加した
> 
> namespace LogGraphTest
> {
>     public partial class drawGraph : Form
>     {
>         public drawGraph()
>         {
>             InitializeComponent();
>         }
> 
>         static bool isGraphLog = false;//テスト用に初期値を入れ替えるためにここに記載
> 
>         private void drawGraph_Load(object sender, EventArgs e)
>         {
>             chart1.ChartAreas[0].CursorX.IsUserEnabled = true;
>             chart1.ChartAreas[0].CursorX.IsUserSelectionEnabled = true;
>             chart1.ChartAreas[0].AxisX.ScaleView.Zoomable = true;
> 
>             drawDataGraph();
>             log_checkBox.Checked = isGraphLog;
>         }
> 
>         public void drawDataGraph()
>         {
>             try
>             {
>                 chart1.Series.Clear();//log_checkBoxをクリックしたときにdrawDataGraph()を再描画するために過去のSeriesをクリアする
>                 if (isGraphLog)
>                 {
>                     this.chart1.ChartAreas[0].AxisX.Minimum = 1.0;//対数表示にはこれが必要
>                 }
>                 else
>                 {
>                     this.chart1.ChartAreas[0].AxisX.Minimum = 0.0;//リニア表示にはこれが必要
>                 }
> 
>                 if (isGraphLog)
>                 {
>                     chart1.ChartAreas[0].AxisX.IsStartedFromZero = false;//対数表示にはこれが必要か?、データも0を含んでいてはいけないが
>                     chart1.ChartAreas[0].AxisX.IsLogarithmic = true;
>                 }
> 
>                 Series[] dseries = new Series[2];//もともと複数のデータ系列があったため配列として[2]としてあるが、このサンプルでは1つなので意味は無い。
>                 dseries[0] = new Series();
>                 dseries[0].ChartType = SeriesChartType.Line;
>                 dseries[0].Name = "DataY1";
>                 dseries[0].Color = Color.Black;
>                 this.chart1.Series.Add(dseries[0]);
> 
>                 int startData = 0;
>                 if (isGraphLog) { startData = 1; }//Logの時はデータがx=0である[0]を飛ばしている。このためLogのグラフが描ける、のでは?
>                 for (int i = startData; i < 11; i++)
>                 {
>                     chart1.Series[dseries[0].Name].Points.AddXY(Form1.mydataX[i], Form1.mydataY1[i]);
>                 }
>             }
>             catch (System.Exception ex)
>             {
>                 Debug.WriteLine("Message = " + ex.Message);
>                 Debug.WriteLine("Source = " + ex.Source);
>                 Debug.WriteLine("StackTrace = " + ex.StackTrace);
>                 throw;//例外を再スローする
>             }
>         }
> 
>         private void log_checkBox_CheckedChanged(object sender, EventArgs e)
>         {
>             if (log_checkBox.Checked)// isGraphLog = log_checkBox.Checkedとも書けると思うが念のために細かく書いた。
>             {
>                 isGraphLog = true;
>             }
>             else
>             {
>                 isGraphLog = false;
>             }
>             drawDataGraph();
>         }
>     }
> }
> = = = = = = = = = = = = ソースはここまで= = = = = = = = = = = = = = = = 
> すみませんが、ご教示よろしくお願いいたします。
> 

引用返信 編集キー/
■94973 / inTopicNo.3)  Re[1]: 対数グラフをリニアに戻すとエラーとなる
□投稿者/ YuO (3回)-(2020/06/08(Mon) 03:51:27)
実行したりせずに、ざっと見ただけですが……。

No94971 (還暦おやじkuma さん) に返信
> **疑問点:アプリを実行してChartType=Lineでリニアグラフが描かれ、チェックボックスでX軸を対数表示にすることまではできますが、もう1度チェックボックスをクリックしてグラフを再描画してリニアに戻そうとするとエラーとなります。描画ルーチンのtry-catchでは引っ掛かりません。
> 原因と解決方法がお分かりでしたらご教示いただけますでしょうか?。

たぶん、対数表示モードのまま最小値を0にしたからエラーになっているのでしょう。
・線形→対数の場合は、最小値を1.0に変更した後に対数モードにする
・対数→線形の場合は、線形モードにした後に最小値を0.0に変更する
とすればよいでしょう。
# というか、対数→線形の軸の変更はどこにあるのでしょうか……。

drawDataGraphメソッドの先頭にブレークポイントを置き、ステップ実行していくと、たぶん
> this.chart1.ChartAreas[0].AxisX.Minimum = 0.0;//リニア表示にはこれが必要
の箇所で例外が発生しているのではないかと思います。
で、その時点でchart1.ChartAreas[0].AxisX.IsLogarithmicの値を見ると恐らくtrueなのではないでしょうか。
引用返信 編集キー/
■94974 / inTopicNo.4)  Re[2]: 対数グラフをリニアに戻すとエラーとなる
□投稿者/ 還暦おやじkuma (3回)-(2020/06/08(Mon) 06:04:49)
No94973 (YuO さん) に返信
> 実行したりせずに、ざっと見ただけですが……。
> # というか、対数→線形の軸の変更はどこにあるのでしょうか……。


YuOさん
早速の回答ありがとうございました!!。おかげさまで一発で解決です!!。ご指摘の通り、対数→線形の軸の変更がありませんでした。つくづく私がマヌケでした。
「実行もせず、ざっと見ただけ」で指摘できるなんてさすがです!。

こういう「掲示板」なるものに(人生60年で)初めて投稿しましたが、すごい方はいらっしゃるもので、便利なものですね。安易にはまってしまいそうな自分が怖い気もします。
お騒がしました&ありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -