teratail header banner
teratail header banner
質問するログイン新規登録
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

3回答

1569閲覧

カラーバーを等級で表したい

mega_ne

総合スコア16

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2019/05/15 09:31

編集2019/05/16 02:40

0

0

python

1fig = plt.figure(figsize=(7.5, 7.5)) 2ax = fig.add_subplot(111) 3 4X, Y = np.meshgrid(x[0:len(x)],y[0:len(y)]) #21 x 21 5F = np.array(F).reshape(len(x)-1,-1) #20 x 20 6 7m = ax.pcolormesh(X, Y, F, cmap='gray') 8fig.colorbar(m, label='A') 9 10plt.show()

用いるデータの一部を以下に示します。
列としては等級、フラックス、X, Yで並んでいます。
本来のデータは数十万行あります。

mag Flux X Y
16.78 0.0007045415735661775 329.399 42.232
16.806 0.0006878704054919076 329.023 42.052
13.317 0.017104351979956002 329.27 42.124
14.469 0.005919794420515654 328.675 41.868
15.511 0.0022672876636957917 329.196 41.957
16.706 0.0007542349013940496 329.374 42.217
16.051 0.0013788169862608637 329.501 42.265
16.962 0.0005958084044128775 329.141 42.167
15.238 0.0029154568968192433 328.801 41.978
16.209 0.0011920833578792421 329.246 42.019
14.663 0.004951156169049099 329.108 41.977
15.384 0.002548629026672342 329.15 42.032
15.111 0.0032772277608275092 328.878 41.979
15.681 0.0019386822097603555 329.284 42.092
16.151 0.0012574960369579535 329.339 42.157

上記のデータをnp.genfromtxtで読み込み、m = data[:,0], F_m = data[:,1]という風に読み込むと

python

1m = np.array([16.78 , 16.806, 13.317, 14.469, 15.511, 16.706, 16.051, 16.962, 15.238, 16.209, 14.663, 15.384, 15.111, 15.681, 16.151]) 2F_m = np.array([0.00070454, 0.00068787, 0.01710435, 0.00591979, 0.00226729, 0.00075423, 0.00137882, 0.00059581, 0.00291546, 0.00119208, 0.00495116, 0.00254863, 0.00327723, 0.00193868, 0.0012575 ]) 3X = np.array([329.399, 329.023, 329.27 , 328.675, 329.196, 329.374, 329.501, 329.141, 328.801, 329.246, 329.108, 329.15 , 328.878, 329.284, 329.339]) 4Y = np.array([42.232, 42.052, 42.124, 41.868, 41.957, 42.217, 42.265, 42.167, 41.978, 42.019, 41.977, 42.032, 41.979, 42.092, 42.157])

となると思います。

少し天文学の知識が必要になる質問です。

上記のコードはデータなどかなり飛ばして抜粋したものですが、やりたいこととしては、
横Xと縦Yの値があり、その間に入る高さFの値を2次元マップで書きたいというものです。
Xの値は328330くらい、Yの値は4143くらい、Fの値は0.0, 0.001...くらいで全て小数(float)です。

ただ単にグラフを描くだけであればこれで終わりなのですが、厄介なことにこのFはフラックスで、描画自体はフラックスのままでいいのですが最終的にカラーバーでフラックスを等級に換算して見やすくしたいです。

なお、Fの中にはあるX, Yの中にデータがないということを意味する0も含まれており、さらに以下に示すフラックスと等級の換算の式で等級がたまたま0になったという場合もあります。

うまくして、フラックスFが元から0であった箇所は真っ黒で、かつ、等級を計算した結果0になったものも含めて等級の値が小さくなると白く、値が大きくなると黒に近づくというカラーバーにしたいです。
おそらくマップ自体はフラックスの値が大きい方が等級が小さくなる、すなわち明るく、フラックスでマップを描いた時に白で表され、逆もまた然りなので大丈夫かなと思っています。

フラックス→等級の換算式
m = -2.5 * log10(F_m/F_0)
m : F_mに対応する等級 /mag
F_m : フラックス /Jy(ジャンスキー)
F_0 : AB等級でのVEGAのフラックス(=3630 /Jy)

難題かもしれませんがよろしくお願いいたします。

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

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

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

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

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

yamato_user

2019/05/15 10:47

難題ではないが、結局したいことは「フラックスFが元から0であった箇所は真っ黒で、かつ、等級を計算した結果0になったものも含めて等級の値が小さくなると白く、値が大きくなると黒に近づくというカラーバーにしたいです。」ということですか?
mega_ne

2019/05/15 14:25

そうなります。
yamato_user

2019/05/16 00:06

> 上記のコードはデータなどかなり飛ばして抜粋したものですが ちゃんとデータを載せてください。グラフ描画用のデータ作成も回答者がやるのはめんどくさすぎます。
mega_ne

2019/05/16 01:25

すみません。 修正いたしました。
yamato_user

2019/05/16 02:08

DataFrameかNumpy配列で
mega_ne

2019/05/16 02:40

すみません。 データの書き方を修正いたしました。
guest

回答3

0

完全に仕様を理解しているか??なのですが。

まず、「等級を計算した結果0になったものも含めて等級の値が小さくなると白く、値が大きくなると黒に近づく」とありますので、等級を計算した結果を mとすると、

Python

1c = ax.pcolormesh(X, Y, m, cmap='gray_r', vmin=0, vmax=20)

のようにcmapを gray_r を使い vminvmax パラメータにて範囲を指定して記述することで実現できます。

また、「フラックスFが元から0であった箇所は真っ黒で」の部分に関しては numpyにて フラックス→等級を計算すると Fの値が0の時は、-2.5*np.log10(0) にて結果が np.inf となり上記の vmax 以上の値となりますので特に何の処理も行わなくても自動的に黒にるかと思います。

以下簡単にサンプルを書きました(計算が合っているのかは不明ですが)ので御確認ください。

Python

1import numpy as np 2import matplotlib.pyplot as plt 3 4x = np.linspace(328,330,21) 5y = np.linspace(41,43,21) 6# F = np.random.choice([0, 0.001, 0.01, 0.1],20*20) 7F = np.random.uniform(0,1,20*20) 8 9X, Y = np.meshgrid(x,y) 10F = np.array(F).reshape(len(x)-1,-1) 11m = -2.5 * np.log10(F/3630) 12 13fig = plt.figure(figsize=(7.5, 7.5)) 14ax = fig.add_subplot(111) 15c = ax.pcolormesh(X, Y, m, cmap='gray_r', vmin=0, vmax=20) 16fig.colorbar(c, label='A') 17 18plt.show()

投稿2019/05/16 03:09

編集2019/05/16 03:16
magichan

総合スコア15898

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

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

magichan

2019/05/16 03:10

いつの間にかサンプルデータが追加されていたのですね・・・ 私のサンプルでは、そのデータを使っておりません。スミマセン
can110

2019/05/16 05:25

当方環境(matplotlib=2.2.2)ではinfはなぜか白くなっちゃいますね。。。
magichan

2019/05/16 06:58

コメントありがとうございました。 たしかにそのようになってますね・・。
mega_ne

2019/05/16 09:42

データを示しておらず申し訳ございません。 こちらも白くなってしまいました...
guest

0

ベストアンサー

「フラックスFが元から0であった箇所は真っ黒で、かつ、等級を計算した結果0になったものも含めて等級の値が小さくなると白く、値が大きくなると黒に近づくというカラーバーにしたいです。」

magichanさんの回答のとおりでよいと思うのですが、なぜか当方環境ではinfが白で描画されるので回避策の提案です。(matplotlibの仕様?)

幸い、元の0は変換後に特殊な値infになるので、変換後のinfを黒を表す大きな値に置き換えればよいかと思います。
下記コード中ではVMAX=20を指定していますが、適宜調整ください。

Python

1import numpy as np 2import matplotlib.pyplot as plt 3 4import matplotlib 5print(matplotlib.__version__) # 2.2.2 6 7x = np.linspace(328,330,3) 8y = np.linspace(41,43,3) 9F = [0, 3630, 363, 36.3] 10 11X, Y = np.meshgrid(x,y) 12F = np.array(F).reshape(2,-1) 13 14m = -2.5 * np.log10(F/3630) 15print(m) 16""" 17[[ inf -0. ] 18 [ 2.5 5. ]] 19""" 20 21# 元から0(変換後のinf)は最大値(黒)に 22VMAX = 20 23m[m == np.inf] = VMAX 24 25fig = plt.figure() 26ax = fig.add_subplot(111) 27m = ax.pcolormesh(X, Y, m, cmap='gray_r', vmin=0, vmax=VMAX) 28fig.colorbar(m, label='A') 29 30plt.show()

イメージ説明

投稿2019/05/16 05:27

can110

総合スコア38352

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

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

magichan

2019/05/16 06:56

「なぜか当方環境ではinfが白で描画される」 マジか・・・・。確認しましたところ確かにそうですね。全く気づいておりませんでした。
mega_ne

2019/05/16 09:43

こちらの方法でうまくいきました。ありがとうございます。 もっと勉強します。
guest

0

コードを書くには2つの段階があります。

(A) 解こうとする問題の定式化
(B) 定式化した問題を特定の機能・文法を持つ言語・ライブラリーを前提として計算機の言葉(コード)に翻訳すること

当然ながら(A)を行うにはその問題の専門領域の知識が必要ですが、問題が天文学であろうと何であろうとその定式化の中には必ずと言ってよいほど「数学の知識」が含まれていると思います。プログラマーは定式化の中の数学的部分についてはそれほど難しいとは感じないことが多いです。何故ならあらゆる問題に取り組む際に共通の道具として使う数学の応用に慣れているからです。もちろんその数学の難易度のレベルは様々であり義務教育を終えた人なら必ず教わっているはずのことから数学の専門家にしか理解が困難な高度なものまであるとは思いますが、多くの問題は義務教育~高校・大学の数学の中で解決できることがら(α)であると思えます。

少なくとも本件については(α)の範囲内に収まった数学の知識と計算機の特徴の知識が必要ではないでしょうか。

  • ある範囲の値[a, b]を別の値[f(a), f(b)]へ写像する手段
    これは(α)の範囲内の知識だと思います。天文学とは直接関係ありません。

  • 計算機のディスプレイで白色光は輝度(フラックスと考えてよいと思います)の量で表す

  • 計算機のディスプレイでは輝度は256段階であるのが普通
    0~255の整数で輝度を表したり、輝度の分解能を意識する必要がないよう0.0~1.0までの浮動小数点数で表現するなど少しバリエーションはあります。

といったことを踏まえていればコードは作れると思います。

フラックスFの値に基づき、等級mを表す画素値をどう計算するかですが、色を画素値[0.0, 1.0]で表現する(ただし0.0は完全な黒, 1.0は完全な白)としますと

・Fが0なら
=>画素値は0.0(黒)
・Fが0以外なら
=>等級を計算し等級の範囲に応じて画素値へ写像

とすればよいです。画素値[0.0, 1.0]への写像の計算式をどうするかですが、それは等級を輝度へどう変換したいかの質問者さん自身の意思により決まることです。それ(定式化)が決まらないとコードに表現することはできません。

ググりますと太陽の等級は-26.7, 月は-12.7らしいので、等級を輝度へ線形に写像するなら

最小の等級最大の等級等級から画素値への写像
6太陽pixel = (m - 6) / (26.7 + 6)
10pixel = (m - 10) / (12.7 + 10)

といった具合になるでしょう。写像の方法には目的によっていろいろ考えることができ、同じ線形写像でも

  • (1) 前述のように特定のFの範囲を定め最小値を画素値0.0とし最大値を画素値1.0へ写像する
  • (2) 輝度の最小値は自分が望む値にすることもできましょう。
    最小輝度を0.5, 最大を1.0にしたってよいのです。要は結果としての画像がどう見えてほしいかです。
  • (3) ある写像を行い、画素値が範囲外になったら[0.0, 1.0]の範囲に丸めるという考え方もある
  • (4) (1)のようにあらかじめ範囲を定めるのではなく、対象画像のFの中で非0のものの最小値を画素値0.0とし最大値を画素値1.0へ写像するといった考え方。

等々のバリエーションが考えられます。いずれにせよ質問者さんの課題は「ある範囲の値を別の値へ写像する」という数学的な応用を本件に適用できないでいることのように思います。


数学は多くの科学(プログラミングもその一種といって差し支えないと思います)の基礎(道具)です。プログラミング初心者の方の場合、大抵は義務教育~高校数学の範囲に有用なテクニックが含まれているにもかかわらずそれをうまく適用できないでいるという状況が目立つ気がします。

もしそうであれば数学を(単なる知識として知っていても)具体的な場面で応用・適用することに慣れていないだけだと思いますので、問題を数学的な面から捉える(数学的アプローチをする)練習をするのがよいのではないかと思います。

投稿2019/05/16 04:59

KSwordOfHaste

総合スコア18404

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

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

KSwordOfHaste

2019/05/16 05:06

回答中「輝度(フラックスと考えてよいと思います)」は質問者さんを混乱させかねない表現かも知れません。ここでいうフラックスとは「ディスプレイを見る人間の感覚に与えるフラックス」のことで星のフラックスのことを言っているのではありません。
mega_ne

2019/05/16 07:56

そうですね... 数学を全然使えていないと思います。 定式化や応用法を考えます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.30%

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

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

質問する

関連した質問