質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

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

Q&A

2回答

5052閲覧

取得した温度をmatplotlibにリアルタイム表示させたい

cmcm_a

総合スコア1

Matplotlib

MatplotlibはPythonのおよび、NumPy用のグラフ描画ライブラリです。多くの場合、IPythonと連携して使われます。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

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

0グッド

0クリップ

投稿2020/06/26 03:50

編集2020/06/26 09:27

前提・実現したいこと

ラズベリーパイで毎秒温度を取得することに成功したので、matplotlibで毎秒反映されるようなグラフを作成したい。
温度取得に使ったセンサーはGROVE-I2C 熱電対アンプというものです。

※あと私自身プログラミング歴は1ヶ月ちょっとです。

温度測定のソースコード

様々なサイトを参考にして作りました。
※ほとんどコピペなのですが、理解出来るようになりたいと思っています。

Python

1import smbus 2from time import sleep 3 4# I2C device: /dev/i2c-1 5bus = smbus.SMBus(1) 6 7# MCP9600: slave address 8address_mcp9600 = 0x60 9 10# MCP9600: register 11reg_devid = 0x20 12reg_temp = 0x10 13 14# Get Temperature 15try: 16 devid = bus.read_byte_data(address_mcp9600, reg_devid) 17 18 typeJ = 0x10 19 typeJ = typeJ <<4 20 filterJ = 0x00 21 typeJ = typeJ | filterJ 22 23 while True: 24 block = bus.read_i2c_block_data(address_mcp9600, 0x100, 2) 25 26 temp_sign = block[0] & 0x80 27 temp_upper = block[0] * 16 28 temp_lower = block[1] * 0.0625 29 30 temp = temp_upper + temp_lower 31 32 if temp_sign == 0x80: 33 temp = (4096 - temp) * -1 34 35 print('%2.2f' % (temp)) 36 37 sleep(1) 38 39except KeyboardInterrupt: 40 pass 41 42

このコードを実行すると下のShellに毎秒温度が測定されるようになっています。
毎秒測定されていきます
この温度をmatplotlibに突っ込んでグラフを作りたい。

matplotlibでグラフ作成

めちゃくちゃなコードになっております。

シンプルにグラフを作るコードを参考にして、先程の温度測定のソースコードとくっつけようと考えました。
x軸にdatetimeで現在時刻、Y軸に取得温度を入れたいと思い。考え付いたのがdeftempsという関数を作るというものです。

Python

1import smbus 2from time import sleep 3 4import matplotlib.pyplot as plt 5import numpy as np 6import datetime 7 8def temps(): 9 # I2C device: /dev/i2c-1 10 bus = smbus.SMBus(1) 11 12 # MCP9600: slave address 13 address_mcp9600 = 0x60 14 15 # MCP9600: register 16 reg_devid = 0x20 17 reg_temp = 0x10 18 19 # Get Temperature 20 try: 21 devid = bus.read_byte_data(address_mcp9600, reg_devid) 22 23 typeJ = 0x10 24 typeJ = typeJ <<4 25 filterJ = 0x00 26 typeJ = typeJ | filterJ 27 28 while True: 29 block = bus.read_i2c_block_data(address_mcp9600, 0x100, 2) 30 31 temp_sign = block[0] & 0x80 32 temp_upper = block[0] * 16 33 temp_lower = block[1] * 0.0625 34 35 temp = temp_upper + temp_lower 36 37 if temp_sign == 0x80: 38 temp = (4096 - temp) * -1 39 40 #グラフに表示したいのでコメント化 41 #print('%2.2f' % (temp)) 42 43# x軸:時刻 Y軸:温度 44x = datetime.datetime.now() 45y = temps() 46# グラフを描画する 47plt.plot(x, y, color='blue') 48# 次の描画まで1秒待つ 49plt.pause(1) 50# グラフをクリア 51line.remove()

エラーなど

実行すると

Shell

1IndentationError: unexpected unindent

x = datetime.datetime.now() にインデントのエラーが出ていました。

教えていただきたいこと

エラーの解決方法。
このコードで毎秒反映されるようなグラフは実現出来るのか。

ソースコードを書きましたが、これよりも良い方法などがございましたら教えていただきたいです。

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

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

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

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

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

mimikyu

2020/06/26 04:23

いくつか確認したいのですが、 IndentationError: unexpected unindent 上記エラー文が出ている箇所はどこでしょうか。 余計なインデントが含まれているというエラー文です。 また、変数yにtemps()から返ってきた値をいれるということですが、 temps()が定義されていないようです。
cmcm_a

2020/06/26 09:31

コメントありがとうございます。 修正できる所は修正いたしました。 エラー文が出ているのは  # x軸:時刻 Y軸:温度 x = datetime.datetime.now() の()の後ろ部分がエラーでした
mimikyu

2020/06/26 09:54

修正頂きありがとうございます。 1・例外処理の書き方に誤りがあります。 try-exceptのexceptが書かれておりません。 私のほうで同様のソースコードにexceptを追記しましたところ IndentationError: unexpected unindent 上記のエラーは解消されました。 2・y = temps() 変数yに温度の値を入れたいとのことでしたので、 temps()にreturn文を追記する必要がございます。 ひとつひとつエラーを改修していくことで、ソースの理解は深まるかと思います。
cmcm_a

2020/06/26 10:30

コメントありがとうございます。 少し前にエラー文が Traceback (most recent call last): File "/home/pi/****/****.py", line 16, in <module> devid = bus.read_byte_data(address_mcp9600, reg_devid) OSError: [Errno 121] Remote I/O error に変わってしまいその対応に追われている状況ですので、解決したら修正させていただきたいと思います。
guest

回答2

0

こんな感じでどうでしょうか

import smbus from time import sleep import matplotlib.pyplot as plt import numpy as np import datetime # I2C device: /dev/i2c-1 bus = smbus.SMBus(1) # MCP9600: slave address address_mcp9600 = 0x60 # MCP9600: register reg_devid = 0x20 reg_temp = 0x10 # Get Temperature try: devid = bus.read_byte_data(address_mcp9600, reg_devid) typeJ = 0x10 typeJ = typeJ <<4 filterJ = 0x00 typeJ = typeJ | filterJ max_plot_num = 10 x = [] y = [] ax = plt.subplot() while True: print(ax) block = bus.read_i2c_block_data(address_mcp9600, 0x100, 2) temp_sign = block[0] & 0x80 temp_upper = block[0] * 16 temp_lower = block[1] * 0.0625 temp = temp_upper + temp_lower if temp_sign == 0x80: temp = (4096 - temp) * -1 # データを追加 x.append(datetime.datetime.now()) y.append(temp) # グラフに表示したいのでコメント化 #print('%2.2f' % (temp)) # グラフを更新 ax.clear() ax.plot(x[-max_plot_num:], y[-max_plot_num:], '-') plt.pause(1) except KeyboardInterrupt: pass

投稿2020/06/26 05:51

magichan

総合スコア15898

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

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

cmcm_a

2020/06/26 09:59

コメントありがとうございます。 コピペさせていただき、実行したのですが Traceback (most recent call last): File "/home/pi/****/****.py, line 20, in <module> devid = bus.read_byte_data(address_mcp9600, reg_devid) OSError: [Errno 121] Remote I/0 error と表示されてしまいました、温度測定のコードを実行しても同じ結果になってしまい、もしや接触不良かなと思い、取り外したり試しましたが変化がありません・・。
guest

0

計測するたびに時刻と温度をリストに格納し、
計測を停止したらそのリストからプロットするようにします。

たとえば、

python

1xs = [] 2temps = [] 3 4try: 5 # ... 6 while True: 7 x = datetime.datetime.now() 8 # ... 9 print('%2.2f' % (temp)) 10 11 xs.append(x) 12 temps.append(temp) 13 14 sleep(1) 15 16except KeyboardInterrupt: 17 plt.plot(xs, temps)

投稿2020/06/26 05:23

kirara0048

総合スコア1399

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問