更改 pyplot 散点 x 增量

Change pyplot scatter x increment

我正在尝试将每天的 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()

您正在将 x 轴上的日期绘制为字符串。这将导致 matplotlib 认为它是一些分类变量(例如 ["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()

日期 (pandas)

在很多情况下,使用真实日期是有利的。 您可以将列转换为日期时间,

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)

要更好地控制坐标轴上日期的外观,您可以使用 matplotlib。例如。要勾选一月和七月的每个月的第一天,并使用带斜杠的日期时间格式,请使用

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()