[解決済み] グラフのY軸に魅力的なリニアスケールを選択する
質問
私たちのソフトウェアで、棒グラフ(または折れ線グラフ)を表示するコードを少し書いています。 すべてうまくいっています。 困っているのは、Y 軸のラベル付けです。
呼び出し元は、Y スケールにどの程度細かくラベル付けしてほしいかを私に伝えることができますが、私は、quot; attractive" のような方法で正確にラベル付けすることに行き詰っているようです。 私は、quot;attractive" を説明できませんし、おそらくあなたもそうでしょうが、私たちはそれを見ればわかりますよね?
ということは、もしデータポイントが
15, 234, 140, 65, 90
そして、ユーザはY軸に10個のラベルを要求し、紙と鉛筆で少し細工をすると出てきます。
0, 25, 50, 75, 100, 125, 150, 175, 200, 225, 250
つまり、(0 を含まない)10 個のラベルがあり、最後のラベルは最高値 (234 < 250) を超えて広がっており、25 個ずつの "nice" 増加しているのです。 もしラベルを8枚要求されたら、30枚の増分が良かったかもしれませんね。
0, 30, 60, 90, 120, 150, 180, 210, 240
9は難しいな。 8か10のどちらかを使って、十分近いということにすればよかったかもしれませんね。 また、いくつかのポイントがマイナスの場合はどうすればいいのでしょうか?
Excelはこの問題にうまく取り組んでいるのがわかりますね。
これを解くための汎用的なアルゴリズム(多少のブルートフォースでも構いません)をご存知の方はいらっしゃいますか? 早くやる必要はないのですが、見栄えは良くしたいです。
どのように解決するのですか?
ずっと前に、私はこれをうまくカバーするグラフモジュールを書きました。灰色の塊を掘り下げると、次のようになります。
- データの下限と上限を決定します。(下限=上限という特殊なケースに注意!
- 範囲を必要な目盛りの量に分割します。
- ティックレンジを適切な量に切り上げます。
- 下限と上限を適宜調整します。
例を見てみましょう。
15, 234, 140, 65, 90 with 10 ticks
- 下限値 = 15
- 上限値 = 234
- 範囲 = 234-15 = 219
- tick range = 21.9です。これは25.0であるべきです
- 新しい下限値 = 25 * round(15/25) = 0
- 新しい上限値 = 25 * round(1+235/25) = 250
つまり、範囲 = 0,25,50,...,225,250 となります。
以下の手順で、素敵なティックレンジを得ることができます。
- 10^x で割って、結果が 0.1 と 1.0 の間になるようにします (1 を除く 0.1 を含む)。
-
は適宜翻訳してください。
- 0.1 -> 0.1
- <= 0.2 -> 0.2
- 0.25 -> 0.25
- 0.3 -> 0.3
- 0.4 -> 0.4
- 0.5 -> 0.5
- 0.6 -> 0.6
- 0.7 -> 0.7
- 0.75 -> 0.75
- 0.8とする。
- 0.9 -> 0.9
- <= 1.0 -> 1.0
- を10^x倍してください。
- 下限値 = 15
- 上限値 = 234
- 範囲 = 234-15 = 219
-
ティックレンジ = 27.375
- 0.27375 を 10^2 で割ると 0.3 となり、(10^2 を掛けて) 30 となります。
- 新しい下限 = 30 * round(15/30) = 0
- 新しい上限値 = 30 * round(1+235/30) = 240
この場合、21.9を10^2で割ると0.219になります。これは <= 0.25 なので、今 0.25 となります。10^2 を掛けると 25 になります。
同じ例を8刻みで見てみましょう。
15, 234, 140, 65, 90 with 8 ticks
となり、要求された結果が得られます;-)。
------ KD によって追加されました ------。
ルックアップテーブルなどを使わずにこのアルゴリズムを実現するコードを紹介します。
double range = ...;
int tickCount = ...;
double unroundedTickSize = range/(tickCount-1);
double x = Math.ceil(Math.log10(unroundedTickSize)-1);
double pow10x = Math.pow(10, x);
double roundedTickRange = Math.ceil(unroundedTickSize / pow10x) * pow10x;
return roundedTickRange;
一般的に、目盛りの数は一番下の目盛りを含むので、実際のY軸のセグメントは目盛りの数より1つ少なくなります。
関連
-
[解決済み】Quickselectの時間の複雑さを説明する
-
[解決済み] Bogosort (a.k.a Monkey Sort)よりも悪いソートアルゴリズムはあるのか?[クローズド]
-
[解決済み] アルゴリズムの教科書では、ソートされた配列について「増加」ではなく「非減少」を使っているのはなぜですか?
-
[解決済み] 解いてみてください。T(n) = T(n-1) + n [重複] とする。
-
[解決済み] 線形時間でのソート?[クローズド]
-
[解決済み] リストの並べ換えをすべて生成するアルゴリズム?
-
[解決済み] ある問題がNP完全であることをどのように証明するか?
-
[解決済み] トライ式と基幹トライ式のデータ構造の違いは何ですか?
-
[解決済み] ユークリッド・アルゴリズムの時間計算量
-
[解決済み] ダイクストラアルゴリズムの時間複雑性計算の理解
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】決定木(比較ソートアルゴリズム)の葉の最短の深さ)
-
[解決済み] NPとco-NPの違いは何ですか?
-
[解決済み] グラフにおいて最小容量が最大となる経路の探索
-
[解決済み] T(n) = 2T(n/2) + O(n) からO(nlogn)を得る方法
-
[解決済み] 素朴な」アルゴリズムとは何か、「閉じた」解とは何か?
-
[解決済み] CLRSの相対的漸近成長に関する問題(表)の解き方について教えてください。
-
[解決済み] 与えられた数列の中に現れない最小の正の整数を求めよ。
-
[解決済み] 二分探索木におけるk番目の最小要素を最適な方法で探す
-
[解決済み] luceneはどのように文書をインデックスするのですか?
-
[解決済み] 円内の点の位置の計算