更改pyplot scatter x increment

时间:2017-10-23 21:41:07

标签: matplotlib scatter-plot

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

Scatter Plot

1 个答案:

答案 0 :(得分:1)

您正在将x轴上的日期绘制为字符串。这将导致matplotlib认为它是一些catogorical变量(例如[“apple”,“banana”,“cherry”])并且它将显示所有标签(这对于这种情况将是有意义的)。

在这里,您不希望有类别,而是真实的日期或数字。首先,您需要确保这些字符串实际上代表日期或数字 - 从列表中删除'92017/01/13'之类的内容。

十进制数

要使用通常的十进制数字,请从函数中移除str强制转换。

decdate = year + ((month-1)*30+day)/365.

enter image description here

完整的复制代码:

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

enter image description here

完整的复制代码:

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。例如。要在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()

enter image description here

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