我正在尝试将每天的GPS位移绘制为散点图。我写了一个函数来将每一天转换为十进制日期。
然而,当我绘制散点图时,它会绘制x轴上的每个日期,它看起来像一个黑条。是否可以改变x轴的增量?
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import datetime
import matplotlib.dates as dates
import random
lst1 = ['2015/01/01','2016/01/01','2017/01/01','2015/01/02',
'2016/01/02','2017/01/02','2015/01/03','2016/01/03','2017/01/03',
'2015/01/04','2015/01/05','2017/01/04','2016/01/04','2016/01/05',
'2015/01/06','2017/01/05','2016/01/06','2015/01/07','2017/01/06',
'2017/01/07','2016/01/07','2015/01/08','2017/01/08','2016/01/08',
'2015/01/09','2016/01/09','2017/01/09','2016/01/10','2017/01/10',
'2015/01/11','2016/01/11','2017/01/11','2015/01/12','2016/01/12',
'2015/01/13','2017/01/12','2016/01/13','92017/01/13','2016/01/14',
'2015/01/14','2017/01/14','2015/01/15','2016/01/15','2017/01/15',
'2016/01/16','2015/01/16','2017/01/16','2017/01/17','2016/01/17',
'2015/01/18','2016/01/18','2017/01/18','2015/01/19','2016/01/19',
'2017/01/19','2015/01/20','2016/01/20','2017/01/20','2015/01/21',
'2016/01/21','2017/01/21','2015/01/22','2016/01/22','2017/01/22',
'2015/01/23','2016/01/23','2017/01/23','2015/01/24','2016/01/24',
'2017/01/24', '2015/01/25', '2016/01/25']
lst2 = random.sample(range(72), 72)
def date2decdate(date):
d = date.split('/')
year = float(d[0])
month = float(d[1])
day = float(d[2])
decdate = str(year + ((month-1)*30+day)/365)
return decdate
df = pd.DataFrame(
{'Date': lst1,
'Elevation': lst2
})
print(df.Date)
# convert displacement to centimeters
df['Elevation']*=100
#df['Northing']*=100
#df['Easting']*=100
# calculate displacement
h = float(df['Elevation'].head(1))
df['Elevation']-=h
# Remove outliers by keeping data points that are within +-3 standard devations
# in the column Elevation
df = df[np.abs(df.Elevation-df.Elevation.median())<=(3*df.Elevation.std())]
df['Date'] = df['Date'].apply(date2decdate) #converts Dates to decimal date
plt.scatter(df.Date, df.Elevation)
plt.xlabel('Dates')
plt.ylabel('Displacement(cm)')
plt.show()
答案 0 :(得分:1)
您正在将x轴上的日期绘制为字符串。这将导致matplotlib认为它是一些catogorical变量(例如[“apple”,“banana”,“cherry”])并且它将显示所有标签(这对于这种情况将是有意义的)。
在这里,您不希望有类别,而是真实的日期或数字。首先,您需要确保这些字符串实际上代表日期或数字 - 从列表中删除'92017/01/13'
之类的内容。
要使用通常的十进制数字,请从函数中移除str
强制转换。
decdate = year + ((month-1)*30+day)/365.
完整的复制代码:
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import random
lst1 = ['2015/01/01','2016/01/01','2017/01/01','2015/01/02',
'2016/01/02','2017/01/02','2015/01/03','2016/01/03','2017/01/03',
'2015/01/04','2015/01/05','2017/01/04','2016/01/04','2016/01/05',
'2015/01/06','2017/01/05','2016/01/06','2015/01/07','2017/01/06',
'2017/01/07','2016/01/07','2015/01/08','2017/01/08','2016/01/08',
'2015/01/09','2016/01/09','2017/01/09','2016/01/10','2017/01/10',
'2015/01/11','2016/01/11','2017/01/11','2015/01/12','2016/01/12',
'2015/01/13','2017/01/12','2016/01/13','2017/01/13','2016/01/14',
'2015/01/14','2017/01/14','2015/01/15','2016/01/15','2017/01/15',
'2016/01/16','2015/01/16','2017/01/16','2017/01/17','2016/01/17',
'2015/01/18','2016/01/18','2017/01/18','2015/01/19','2016/01/19',
'2017/01/19','2015/01/20','2016/01/20','2017/01/20','2015/01/21',
'2016/01/21','2017/01/21','2015/01/22','2016/01/22','2017/01/22',
'2015/01/23','2016/01/23','2017/01/23','2015/01/24','2016/01/24',
'2017/01/24', '2015/01/25', '2016/01/25']
lst2 = random.sample(range(72), 72)
def date2decdate(date):
d = date.split('/')
year = float(d[0])
month = float(d[1])
day = float(d[2])
decdate = year + ((month-1)*30+day)/365.
return decdate
df = pd.DataFrame( {'Date': lst1, 'Elevation': lst2 })
df['Elevation']*=100
h = float(df['Elevation'].head(1))
df['Elevation']-=h
df = df[np.abs(df.Elevation-df.Elevation.median())<=(3*df.Elevation.std())]
df['Date'] = df['Date'].apply(date2decdate) #converts Dates to decimal date
plt.scatter(df.Date, df.Elevation)
plt.xlabel('Dates')
plt.ylabel('Displacement(cm)')
plt.show()
在许多情况下,使用实际日期是有利的。 您可以将列转换为datetime,
df['Date'] = pd.to_datetime(df["Date"], format="%Y/%m/%d")
然后可以通过
直接绘制df.plot(x="Date", y="Elevation")
# or, if you want scatter points
df.plot(x="Date", y="Elevation", ls="", marker="o")
完整的复制代码:
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import random
lst1 = ['2015/01/01','2016/01/01','2017/01/01','2015/01/02',
'2016/01/02','2017/01/02','2015/01/03','2016/01/03','2017/01/03',
'2015/01/04','2015/01/05','2017/01/04','2016/01/04','2016/01/05',
'2015/01/06','2017/01/05','2016/01/06','2015/01/07','2017/01/06',
'2017/01/07','2016/01/07','2015/01/08','2017/01/08','2016/01/08',
'2015/01/09','2016/01/09','2017/01/09','2016/01/10','2017/01/10',
'2015/01/11','2016/01/11','2017/01/11','2015/01/12','2016/01/12',
'2015/01/13','2017/01/12','2016/01/13','2017/01/13','2016/01/14',
'2015/01/14','2017/01/14','2015/01/15','2016/01/15','2017/01/15',
'2016/01/16','2015/01/16','2017/01/16','2017/01/17','2016/01/17',
'2015/01/18','2016/01/18','2017/01/18','2015/01/19','2016/01/19',
'2017/01/19','2015/01/20','2016/01/20','2017/01/20','2015/01/21',
'2016/01/21','2017/01/21','2015/01/22','2016/01/22','2017/01/22',
'2015/01/23','2016/01/23','2017/01/23','2015/01/24','2016/01/24',
'2017/01/24', '2015/01/25', '2016/01/25']
lst2 = random.sample(range(72), 72)
df = pd.DataFrame( {'Date': lst1, 'Elevation': lst2 })
df['Elevation']*=100
h = float(df['Elevation'].head(1))
df['Elevation']-=h
df = df[np.abs(df.Elevation-df.Elevation.median())<=(3*df.Elevation.std())]
#Convert to datetime
df['Date'] = pd.to_datetime(df["Date"], format="%Y/%m/%d")
#plot with pandas wrapper
df.plot(x="Date", y="Elevation", ls="", marker="o")
plt.xlabel('Dates')
plt.ylabel('Displacement(cm)')
plt.show()
要更好地控制轴上日期的外观,可以使用matplotlib。例如。要在1月和7月的每个月中打勾,并使用带有斜杠的日期时间格式,请使用
plt.scatter(df['Date'].values,df['Elevation'])
plt.gca().xaxis.set_major_locator(dates.MonthLocator((1,7)))
plt.gca().xaxis.set_major_formatter(dates.DateFormatter("%Y/%m/%d"))
plt.gcf().autofmt_xdate()
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import matplotlib.dates as dates
import random
lst1 = ['2015/01/01','2016/01/01','2017/01/01','2015/01/02',
'2016/01/02','2017/01/02','2015/01/03','2016/01/03','2017/01/03',
'2015/01/04','2015/01/05','2017/01/04','2016/01/04','2016/01/05',
'2015/01/06','2017/01/05','2016/01/06','2015/01/07','2017/01/06',
'2017/01/07','2016/01/07','2015/01/08','2017/01/08','2016/01/08',
'2015/01/09','2016/01/09','2017/01/09','2016/01/10','2017/01/10',
'2015/01/11','2016/01/11','2017/01/11','2015/01/12','2016/01/12',
'2015/01/13','2017/01/12','2016/01/13','2017/01/13','2016/01/14',
'2015/01/14','2017/01/14','2015/01/15','2016/01/15','2017/01/15',
'2016/01/16','2015/01/16','2017/01/16','2017/01/17','2016/01/17',
'2015/01/18','2016/01/18','2017/01/18','2015/01/19','2016/01/19',
'2017/01/19','2015/01/20','2016/01/20','2017/01/20','2015/01/21',
'2016/01/21','2017/01/21','2015/01/22','2016/01/22','2017/01/22',
'2015/01/23','2016/01/23','2017/01/23','2015/01/24','2016/01/24',
'2017/01/24', '2015/01/25', '2016/01/25']
lst2 = random.sample(range(72), 72)
df = pd.DataFrame( {'Date': lst1, 'Elevation': lst2 })
df['Elevation']*=100
h = float(df['Elevation'].head(1))
df['Elevation']-=h
df = df[np.abs(df.Elevation-df.Elevation.median())<=(3*df.Elevation.std())]
df['Date'] = pd.to_datetime(df["Date"], format="%Y/%m/%d")
plt.scatter(df['Date'].values,df['Elevation'])
plt.gca().xaxis.set_major_locator(dates.MonthLocator((1,7)))
plt.gca().xaxis.set_major_formatter(dates.DateFormatter("%Y/%m/%d"))
plt.gcf().autofmt_xdate()
plt.xlabel('Dates')
plt.ylabel('Displacement(cm)')
plt.show()