あなたと同様のデータを生成した後:
import numpy as np
import matplotlib.pyplot as plt
plt.ioff()
import matplotlib.dates as mdates
import datetime as dt
import time
# --- Build date blocks ---
now = time.time() # first time
delta_time = 60 # distance between points in seconds
n_jumps = 10 # number of pieces with no data
avg_jump_size = 60*60*24 # 86400 s = 1 day
jumps = abs(np.random.normal(avg_jump_size/2.,
avg_jump_size/2,
n_jumps+1)) + avg_jump_size/2.
# `abs` just to make sure the jump is positive, and ` + avg_jump_size/2.` to
# make sure it's larger than the time step.
avg_n_poins_per_block = 2*60*60/delta_time # 2 hours of acquisition per block
blocks_sizes = abs(np.random.normal(avg_n_poins_per_block/2.,
avg_n_poins_per_block/2.,
n_jumps+1)) + avg_n_poins_per_block/2.
times = np.array([]) # array to place all dates
for i in range(n_jumps):
block = np.arange(now, now+delta_time*blocks_sizes[i], delta_time)
times = np.concatenate((times, block))
now += jumps[i]
# last block
block = np.arange(now, now+delta_time*blocks_sizes[-1], delta_time)
times = np.concatenate((times, block))
def time2mdate_str(number=None):
"""
Convert a time given by `time.time()` to a `datetime` instance
from `matplotlib.mdate`.
"""
if number is None:
number = time.time()
# time.time() returns the number of seconds since the Epoch
# (1970-01-01 00:00:00).
# But mdate represents time in days since 0001-01-01 00:00:00, plus 1 day.
# (http://matplotlib.org/api/dates_api.html)
# So we convert to days:
number /= 60*60*24
# and then we add the 1969 years:
# http://www.rapidtables.com/calc/time/days-in-year.htm
number += 1969*365.2425
# and now it should be off by only (!) ~11h (close enough)
a = mdates.num2date(number)
return a
# list of time strings:
dates_test = [time2mdate_str(t).strftime("%Y-%m-%d %H:%M:%S") for t in times]
# some random data:
errors = np.random.normal(0.025, 0.01, len(times))
xaxis = np.arange(len(errors)) # omiter
# Original code:
x = [dt.datetime.strptime(d,'%Y-%m-%d %H:%M:%S') for d in dates_test]
x = [mdates.date2num(i) for i in x]
fig, ax = plt.subplots(nrows=3, figsize=(8, 6), sharex = True)
ax[0].plot(xaxis, errors)
ax4 = ax[0].twiny()
ax4.plot_date(x, errors, fmt="r-")
ax4.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m \n%H:%M'))
fig.tight_layout()
fig.show()
私の最初の考えは、それぞれを分離するましたデータブロック(あなたまだ)最初のxの値は0時00分も持っているし、最初の時間を引くことができます。
# break into blocks:
x = np.array(x)
deltas = x[1:] - x[:-1]
# assume there's no break right after the first value and
# find where the difference between consecutive times is larger
# than 1.1*deltas[0] (margin of 1.1* for float comparison)
break_indexes = np.where(deltas > deltas[0]*1.1)[0]+1
# add borders (will be useful for iterating over the list):
break_indexes = np.concatenate(([0],break_indexes,[-1]))
n_jumps = len(break_indexes) - 1
# offset to make sure each line does not overlap with another:
offset = 1.5*np.max(errors)
fig2, ax2 = plt.subplots(figsize=(8, 6))
for i in range(n_jumps):
i_0 = break_indexes[i]
slice_ = slice(i_0, break_indexes[i+1])
ax2.plot(x[slice_]-x[i_0]+x[0], errors[slice_]+offset*i, label=dates_test[i_0])
ax2.xaxis.set_major_formatter(mdates.DateFormatter('%H:%M'))
ax2.set_xlim(x[0])
ax2.legend()
fig2.tight_layout()
fig2.show()
その後、私はあなたがそれが役に立つティックとして、各時間ブロックの開始を使用することを見つけることができると思いましたこれは、ラベルの重ね合わせにつながることができますが、最後に
# use blocks as ticks:
fig3, ax3 = plt.subplots(nrows=3, figsize=(8, 6), sharex = True)
ax3[0].plot(xaxis, errors)
ax3 = ax3[0].twiny()
ax3.plot_date(x, errors, fmt="r-")
ax3.set_xticks(x[break_indexes][:-1])
ax3.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m \n%H:%M'))
fig3.tight_layout()
fig3.show()
そして、私はあなたがレムにしたいかもしれないと思いましたこれらのギャップオベが、適切な場所にタグを保つ:
# use blocks as ticks and eliminate the gaps:
# (could have used the inverse of this to create those gaps)
x_without_gaps = x.copy()
delta = x[1] - x[0]
for i in range(1,n_jumps):
i0 = break_indexes[i]
i1 = break_indexes[i+1]
if i1 == -1:
i1 = None
x_without_gaps[i0:i1] -= x_without_gaps[i0] - x_without_gaps[i0-1] - delta
#x_without_gaps += x[0]
fig4, ax4 = plt.subplots(nrows=3, figsize=(8, 6), sharex = True)
ax4[0].plot(xaxis, errors)
ax4[0].set_xlim(0,len(errors)-1)
ax5 = ax4[0].twiny()
ax5.plot_date(x_without_gaps, errors, fmt="r-")
ax5.set_xticks(x_without_gaps[break_indexes][:-1])
ax5.set_xticklabels([date.strftime('%d/%m \n%H:%M') for date in
mdates.num2date(x[break_indexes][:-1])])
# the following line would clear the values placed!
#ax5.xaxis.set_major_formatter(mdates.DateFormatter('%d/%m \n%H:%M'))
fig4.tight_layout()
fig4.show()
古い結果を間違った目盛りラベル(新しい例のラベルは明らかに異なっているので、データは各ランでランダム化され、と私あなたが本当に赤い背景の青い線を見ることができないので、一致がうまくいくように注意してください。そのためにxlim
を設定してください。
あなたは試してみて、自分の所望の値に(http://matplotlib.org/examples/ticks_and_spines/tick-formatters.html)[ティックを編集]、およびすることができます[この例]( http://matplotlib.org/examples/axes_grid/demo_parasite_axes2.html)は有用かもしれません – berna1111
また、日付に対するプロットはすべてのデータを取り上げているようですが、プロットと同じようにスムーズに散らばっているわけではありません。いくつかの日付の周りに集まった。タイムスタンプがすべて同じ間隔で正しく変換されていますか? – berna1111
@ berna1111あなたの返事をありがとう。 i)この例では、この例では役に立たないと思う。 ii)それは良い点です。タイムスタンプは等間隔ではありませんが、これはまさにそのようなものです。だからこそ私は実際のダニよりもティックラベルとしてそれらを使いたいのです。 – ninjaSurfer