アプリ版:「スタンプのみでお礼する」機能のリリースについて

先日は御回答ありがとうございました。
ご意見を参考に、以下のようなプログラムを作成しました。
このプログラムより、グラフを作成しようとしています。しかし、x2,y2でプロットしようとした際にエラーは出ませんが、グラフが空欄で出力されてしまいます。
x,yのでグラフを作成するとデータ列がきちんと反映されたグラフになります。
x2及び(もしくはどちらか)y2にデータが読み込まれていないことが原因だと思いますが、以下のコードのどこに問題があるのでしょうか?御回答よろしくお願いします。

import numpy as np
import matplotlib.pyplot as plt
import sys, string
from matplotlib.widgets import MultiCursor

f1 = open("SampleData.txt", "r")

x = list()
y = list()

for line in f1:
s = line.split(",")
xx = s[0]
yy = s[1][:-1]
x.append(xx)
y.append(yy)

f1.close()

x2 = list()
y2 = list()

def main():

f1 = open("SampleData.txt", "r")

for line in f1:
t = line.split(",")
p = t[0]
y1 = t[1][:-1]
if p <= 2 :
dsum = sum(y1)
if p >= 2 and p <= 4:
dsum = sum(y1)
else:
dsum = sum(y1)
x2.append(p)
y2.append(dsum)
f1.close()

plt.plot(x2, y2, "o", c="r", mec="r")


plt.title("test")
plt.xlabel("x axis label")
#plt.xscale("log")
plt.ylabel("y axis label", fontsize = "20")

plt.show()

なお、読み込みたいデータファイルは
x,y
1,2
2,4
3,6
4,8
5,10
6,12

です。
xに制限をかけて、その範囲内でyを積算したヒストグラムを作りたいと考えています。
よろしくお願いいたします。

A 回答 (4件)

> 10000個プロットを打ちたい場合は1万回手動でx2の範囲を指定しなければいけないということなのでしょうか?



具体的にどのような範囲指定を行うのかが分らないので何とも言えないのですが
手動でも良いし、別ファイルに書かれた値を読み込んでも良いです。


等間隔であるならば内包表現が良いと思います。使用方法の詳細はPythonのマニュアルを参照ください。

[2*x for x in range(3)] #=> [0, 2, 4]

http://docs.python.jp/3.5/tutorial/datastructure …
    • good
    • 0
この回答へのお礼

回答ありがとうございました。
非常に丁寧に回答してくださったお陰で解決できそうです。
ベストアンサーに選ばせていただきました。

また、似たような質問をさせていただくこともあろうかと思いますが、その際もよろしくお願いいたします。

お礼日時:2016/05/28 03:37

> もう一つお伺いしたいのですが、x2やy2の要素数が1000個とかになり、非常に大きい場合はどのように対処すればよいのでしょうか?



それとも xの範囲の数が3つでなく、もっと増えるということでしょうか?
でしたら以下でどうでしょう?

x2には、各範囲の上限値をあらかじめ設定しておいて下さい。

----------
is_header = True

x2 = [2, 4, 10000] # 各範囲の上限値を設定
dsum = [0] * len(x2) #=> [0, 0, 0] x2の要素数と同じ

with open("SampleData.txt", "r") as f1:
  for line in f1:
    if is_header:
      is_header = False
      continue
    t = line.strip().split(",")
    p = int( t[0] )
    y1 = int( t[1] )

    i = 0
    while i < len(x2):
      if p < x2[i]:
        dsum[i] += y1
        break
      i += 1


xx2 = ['< ' + str(x) for x in x2]
y2 = dsum

print(xx2) #=> ['< 2', '< 4', '< 10000']
print( y2) #=> [2, 10, 30]
    • good
    • 0
この回答へのお礼

なるほど!ありがとうございます。
上手くプロットできました。
>x2 = [2, 4, 10000] # 各範囲の上限値を設定
10000個プロットを打ちたい場合は1万回手動でx2の範囲を指定しなければいけないということなのでしょうか?
理解が追い付いていなくて申し訳ありません。
もし、大量のプロットを打ちたい場合にもっと良い方法があるのでしょうか?

お礼日時:2016/05/26 21:45

こんな感じですか?



※ x2 = list() ~ f1.close()部分の置き換えです。
※ 段付けの為、行頭に全角スペースを付けています。

---------
is_header = True
dsum0 = 0 # 0 <= y < 2
dsum2 = 0 # 2 <= y < 4
dsum4 = 0 # 4 <= y

with open("SampleData.txt", "r") as f1:
  for line in f1:
    if is_header: # ヘッダスキップ
      is_header = False
      continue
    t = line.strip().split(",")
    p = int( t[0] )
    y1 = int( t[1] )

    if p < 2 :
      dsum0 += y1
    elif p >= 2 and p < 4:
      dsum2 += y1
    else:
      dsum4 += y1

x2 = ['0-1', '2-3', '4-']
y2 = [dsum0, dsum2, dsum4]

print(x2) #=> ['0-1', '2-3', '4-'] 要素は文字列
print(y2) #=> [2, 10, 30]   要素は数値
    • good
    • 1
この回答へのお礼

御親切な回答ありがとうございました。
凄く参考になりました。
もう一つお伺いしたいのですが、x2やy2の要素数が1000個とかになり、非常に大きい場合はどのように対処すればよいのでしょうか?
教えていただけると非常に助かります。

お礼日時:2016/05/26 18:30

前にも書きましたが、ここでは空白がまとめられてしまうため、Pythonで重要な字下げがわからなくなります。


そのため、はっきりしたことは言えませんが


def main():
で、main言う名前の関数を定義しています。
※ Pythonでは純粋に「mainという名前の関数」でしかありません。
 C/C++のように「最初はここから実行される」といった特別な意味はありません。

エラーにならないけどグラフが空、ということは、
def main():
から
f1.close()
辺りまでが「mainという名前の関数」を定義しているだけで、実行されていないのではないでしょうか?
def main(): の行を削除して、字下げを整えましょう。


その上で問題になりそうなのは

p = t[0]
if p <= 2 :
このとき、pは文字列です。 p<=2 は文字列と数値の比較になります。
http://docs.python.jp/2/library/stdtypes.html#st …
> 数値型間の比較か文字列間の比較でないかぎり、異なる型のオブジェクトを比較しても等価になることはありません
> これらのオブジェクトの順番付けは一貫してはいますが任意のものです

つまり、「異なる型のオブジェクトの比較」となるので、 '2'==2 とはなりません。
> CPython implementation detail: 数値型を除き、異なる型のオブジェクトは型の名前で順番付けされます
とあるので、 p<=2 は 'str'<='int' であり、常にFalse ということになります。( '1'<=2 はFalseになります )


dsum = sum(y1)
ここも、y1が文字列なので、 sumで計算することができません。

p = t[0]
y1 = t[1][:-1]
の時点で数値にしておくのがよいでしょう。


また、データファイルの1行目「x,y」を無視する処理は必要でしょう。

なお
if p <= 2 :
dsum = sum(y1)
if p >= 2 and p <= 4:
dsum = sum(y1)
else:
dsum = sum(y1)
で何がしたいかがわからないので、正しいかどうかは判断できません。
    • good
    • 0
この回答へのお礼

なるほど・・・
C++などと全く違うのでなかなか難しいです。
何度も御回答ありがとうございました。

お礼日時:2016/05/26 18:31

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!