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

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

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

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

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

1回答

2461閲覧

続・時系列ベクトル図の作成方法について(python)

wtxa111

総合スコア18

Matplotlib

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

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2018/10/19 03:50

プログラミング初心者です。いつもお世話になっております。
グラフ(時系列ベクトル図)の作成についての続きです。
再度ご質問したくよろしくお願い致します。

#モジュールのインポート import pandas as pd import numpy as np import matplotlib.pyplot as plt #csvの読み込み df = pd.read_csv('ocean_current2.csv',encoding='ANSI',parse_dates=[0]) a = df['current'] b = df['orient'] #ベクトルの成分計算 u = a*np.sin(b) v = a*np.cos(b) #ベクトルの起点 time_len = len(df['datetime']) x = np.arange(time_len) y = np.zeros(len(x)) #X軸のラベル dt_labels = [dt.strftime('%m:%d') for dt in df['datetime']] fig, ax = plt.subplots(1,1,figsize=(10, 5)) ax.axhline(color='black', linewidth=1) ax.set_xticklabels(dt_labels, rotation=0, fontsize='small') #ベクトル表示 q = ax.quiver(x, y, u, v,width=0.002,headlength=0, headwidth=0, headaxislength=0) #y軸のラベル plt.yticks(np.arange(-50.0,50.0,10)) #y=0にラインを表示 ax.axhline(color='black', linewidth=1) #ベクトルのキー表示 ax.quiverkey(q, 0.1, 0.9, 30,'? cm/s', labelpos='N', coordinates='axes') #軸にラベルを表記 ax.set_xlabel('datetime') ax.set_ylabel('current(cm/s)') plt.show()

![イメージ説明

皆様のおかげで、描きたい物に近づけることができました。
しかし、まだ完成には至っておりません。
①まず、軸の目盛と各線の長さが対応していません。

以下にデータフレームを示します。
10分毎にcurrent(速度cm/s)とorient(向き、北を0度として時計回り)を計測しています。

datetime current orient

0 2018-05-29 20:00:00 19.3 46.2
1 2018-05-29 20:10:00 20.2 46.7
2 2018-05-29 20:20:00 21.7 47.4
3 2018-05-29 20:30:00 23.7 47.3
4 2018-05-29 20:40:00 25.3 45.7
5 2018-05-29 20:50:00 26.9 45.7
.. ... ... ...
140 2018-05-30 19:20:00 33.7 78.8
141 2018-05-30 19:30:00 34.3 76.5
142 2018-05-30 19:40:00 33.3 76.7
143 2018-05-30 19:50:00 30.1 74.4
144 2018-05-30 20:00:00 31.4 75.0

currentの数値が最大値で40近くあるのですが、線分の長さがY軸の目盛の幅と大きく乖離しています。
これを対応させるにはどうしたらよろしいでしょうか?

②ベクトルのキーを左上に挿入したのですが、これを実際の線分の長さに対応した基準バーにするには
どういう方法があるのでしょうか?今は適当に長さ30と入れておりますが…

③X軸の表示もいささかおかしいものになっています。'%m:%d'で月日指定にしているのですが、
05:29と時刻表記のようになっており、また、途中で日付が5/30に変わるのですが、反映されている
様子がありません。どうしてなのでしょうか?

自分の理解が追い付いておらず、ご迷惑をおかけしております。
どなたか、ご教授頂ければ幸いです。

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

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

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

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

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

guest

回答1

0

ベストアンサー

問題点 1

まず、軸の目盛と各線の長さが対応していません。

scale_units='y', scale=1. を指定

q = ax.quiver(x, y, u, v, width=0.002, scale_units='y', scale=1., headlength=0, headwidth=0, headaxislength=0)

scale : None, float, optional
Number of data units per arrow length unit, e.g., m/s per plot width;
a smaller scale parameter makes the arrow longer. Default is None.

scale_units : [ 'width' | 'height' | 'dots' | 'inches' | 'x' | 'y' | 'xy' ], None, optional
the arrow length unit. Default is None.

scale_units で矢印の長さの単位を指定 y を指定した場合、y 軸のスケールになる。
scale はその場合のスケーリング係数。scale=0.5 にした場合は y 軸方向の1は矢印の長さ2に対応。なので、scale=1 にすると等倍になる。

問題点 2

ベクトルのキーを左上に挿入したのですが、これを実際の線分の長さに対応した基準バーにするにはどういう方法があるのでしょうか?

1 の設定と同じスケールになる。

問題点 3

X軸の表示もいささかおかしいものになっています。'%m:%d'で月日指定にしているのですが、

05:29と時刻表記のようになっており、また、途中で日付が5/30に変わるのですが、反映されている
様子がありません。どうしてなのでしょうか?

datetime 型を str 型に変換している以下の部分で、日時ラベルの書式は設定できる。

dt_labels = np.array([dt.strftime('%m:%d') for dt in df['datetime']])

dt_labels = np.array([dt.strftime('%m/%d') for dt in df['datetime']])

全部のラベルを表示すると、きつくなってしまうので、いくつか選んで表示するようにします。

ax.set_xticks(x[::30]) ax.set_xticklabels(dt_labels[::30], rotation=0, fontsize='small')

サンプルコード

データ作成

python

1import csv 2import numpy as np 3from datetime import datetime, timedelta 4 5data = [] 6for dt in np.arange(datetime(2018, 5, 29, 0), 7 datetime(2018, 5, 30, 23), 8 timedelta(minutes=10)).astype(datetime): 9 current = np.random.uniform(15, 40) 10 orient = np.random.uniform(40, 70) 11 data.append({'datetime': dt.isoformat(), 'current': current, 'orient': orient}) 12 13with open('data.csv', 'w', newline='') as f: 14 writer = csv.DictWriter(f, fieldnames=data[0].keys()) 15 writer.writeheader() 16 writer.writerows(data)

データ読み込み、描画

python

1# モジュールのインポート 2import matplotlib.pyplot as plt 3import numpy as np 4import pandas as pd 5 6# csv の読み込み 7df = pd.read_csv('data.csv', parse_dates=['datetime']) 8df = df.iloc[10:100] # 11 行目 ~ 100行目まで選択 9 10dt = df['datetime'] 11a = df['current'] 12b = df['orient'] 13 14#ベクトルの成分計算 15u = a * np.sin(b) 16v = a * np.cos(b) 17#ベクトルの起点 18time_len = len(dt) 19x = np.arange(time_len) 20y = np.zeros(len(x)) 21 22fig, ax = plt.subplots(figsize=(10, 5)) 23# 水平線 24ax.axhline(color='black', linewidth=1) 25# X軸の目盛りを設定する。 26dt_labels = np.array([d.strftime('%m/%d') for d in dt]) 27ax.set_xticks(x[::30]) 28ax.set_xticklabels(dt_labels[::30], rotation=0, fontsize='small') 29# y軸の目盛りを設定する。 30ax.set_ylim(-55, 55) 31plt.yticks(np.arange(-50, 50.1, 10)) 32#ベクトル表示 33q = ax.quiver(x, y, u, v, width=0.002, scale_units='y', scale=1., 34 headlength=0, headwidth=0, headaxislength=0) 35#y=0にラインを表示 36ax.axhline(color='black', linewidth=1) 37#ベクトルのキー表示 38ax.quiverkey(q, 0.1, 0.9, 30,'? cm/s', labelpos='N', coordinates='axes') 39# x, y軸にラベルを表記 40ax.set_xlabel('datetime', fontsize=13) 41ax.set_ylabel('current (cm/s)', fontsize=13) 42 43plt.show()

イメージ説明

追記

以下のようにして DataFrame から特定の範囲の行だけ抽出できます。

df = df.iloc[10:100] # 11 行目 ~ 100行目まで選択

(x[::10])について、何となくは理解できましたが、もう少し解説して頂けませんでしょうか?

数字はデータセットの数(行数)を示しているのだと思いますが、:2つの意味合いは何でしょうか?

Python のスライス操作です。リストから部分リストを作成できます。
詳しくは こちら を見てください。

array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(array[::2]) # [0, 2, 4, 6, 8, 10] print(array[:5]) # [0, 1, 2, 3, 4] print(array[2:7:2]) # [2, 4, 6]

追記

  • 方法1

figsize=(横、縦) で横方向を大きくする。

fig, ax = plt.subplots(figsize=(15, 5))

イメージ説明

  • 方向2

データをスライサーを使って数個おきに表示するようにする。
5行おきにする。

df = df.iloc[::5]

投稿2018/10/19 04:54

編集2018/10/19 09:16
tiitoi

総合スコア21954

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

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

wtxa111

2018/10/19 08:35

データまでも用意して再現して頂きありがとうございます。 非常に助かりました、また一歩前進できました。 ※なお、numpyの三角関数はラジアン角で指定されることに気づいたので、  そこはnp.radians()で修正しました。 もしもよければ、より詳細に教えて頂きたい点があるのですが。 ①データフレームの自分が欲しい部分だけをグラフ化するコードはありますでしょうか? 例えば、上記のデータは0~144の145行あるのですが、例えばそのうちの50~100のみ を選んでグラフ化する、といったような事です。 ②(x[::10])について、何となくは理解できましたが、もう少し解説して頂けませんでしょうか? 数字はデータセットの数(行数)を示しているのだと思いますが、:2つの意味合いは何でしょうか? どうぞよろしくお願い致します。 次はグラフの分割やグラフの中に別の要素のグラフの挿入に挑戦したいと考えています。
tiitoi

2018/10/19 08:49

追記しました。x[::10] はスライス操作で元の配列 x から10個おきに要素を取り出した部分配列を作成しています。 Python 言語の仕組みなので、追記のURLを参考にしてください。
wtxa111

2018/10/19 09:09

いつもありがとうございます。大変参考になります。 もう1点だけ、データをプロットする際の幅を変えることは可能でしょうか? ベクトルの線分の根本と線分の根本の間隔を広くして見えやすくする、という感覚です。 少し的外れな質問かもしれませんが、思い当たることがあればよろしくお願い致します。
tiitoi

2018/10/19 09:16

追記したように、図自体を大きくするか、表示するデータを間引く (5行おき) しかないです。
wtxa111

2018/10/19 09:21

何度もありがとうございました。いろいろと試してみます。 また次の機会も何卒よろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問