Python初学者/第一张海报。
我在添加颜色条到散点图时遇到麻烦。我有两种类型的绘图:一种显示所有按日期颜色编码的数据,另一种仅显示按日期颜色编码的数据的最大值。在第一种情况下,我可以使用df.index(即日期时间)来制作颜色条,但是在第二种情况下,我将使用df2 ['col']。idxmax来生成颜色,因为我的df2是df我正在用来在数据中生成每日最大值的.groupby对象,它没有可访问的索引。
对于第一种绘图,我已经成功地使用下面的代码生成了基于日期的颜色条,并通过在线示例将它们拼凑在一起:
fig, ax = plt.subplots(1,1, figsize=(20,20))
smap=plt.scatter(df.col1, df.col2, s=140,
c=[date2num(i.date()) for i in df.index],
marker='.')
cb = fig.colorbar(smap, orientation='vertical',
format=DateFormatter('%d %b %y'))
但是对于第二种情节,我试图使用df2 ['col']。idxmax而不是df.index来创建日期系列,但以下操作无效:
for n in cols1:
for m in cols2:
fig, ax = plt.subplots(1,1, figsize=(15,15))
maxTimes=df2[n].idxmax()
PlottableTimes=maxTimes.dropna() #some NaNs in the
#.idxmax series were giving date2num trouble
smap2=plt.scatter(df2[n].max(), df2[m].max(),
s=160, c=[date2num(i.date()) for i in PlottableTimes],
marker='.')
cb2 = fig.colorbar(smap2, orientation='vertical',
format=DateFormatter('%d %b %y'))
plt.show()
错误是:“ rgba序列的长度应为3或4”
因为错误是在抱怨color参数,所以我分别检查了各个绘图命令中color(即c =)参数的输出,并且两者看起来都与我相似,所以我不知道为什么一种颜色有效,而另一种无效:
一种有效的方法:
[736809.0, 736809.0, 736809.0, 736809.0, 736809.0, 736809.0, 736809.0, 736809.0, 736809.0, 736809.0, ...]
一个不起作用的:
[736845.0, 736846.0, 736847.0, 736848.0, 736849.0, 736850.0, 736851.0, 736852.0, 736853.0, 736854.0, ...]
有什么建议或解释吗?我正在运行python 3.5.2。预先感谢您帮助我理解这一点。
编辑1:我制作了以下示例供其他人探索,在此过程中,问题的症结与我的第一个问题不同。下面的代码按照我想要的方式工作:
df=pd.DataFrame(np.random.randint(low=0, high=10, size=(169, 8)),
columns=['a', 'b', 'c', 'd', 'e','f','g','h']) #make sample data
date_rng = pd.date_range(start='1/1/2018', end='1/8/2018', freq='H')
df['i']=date_rng
df = df.set_index('i') #get a datetime index
df['ts']=date_rng #get a datetime column to group by
from pandas import Grouper
df2=df.groupby(Grouper(key='ts', freq='D'))
for n in ['a','b','c','d']: #now make some plots
for m in ['e','f','g','h']:
print(m)
print(n)
fig, ax = plt.subplots(1,1, figsize=(5,5))
maxTimes=df2[n].idxmax()
PlottableTimes=maxTimes.dropna()
smap=plt.scatter(df2[n].max(), df2[m].max(), s=160,
c=[date2num(i.date()) for i in PlottableTimes],
marker='.')
cb = fig.colorbar(smap, orientation='vertical',
format=DateFormatter('%d %b %y'))
plt.show()
我的真实数据与本示例之间的唯一区别是,我的真实数据中散布着许多NaN。因此,我认为出了什么问题了,因为'c ='参数不够长,使plotting命令无法将其解释为覆盖整个日期范围...?例如,如果我手动输入c =命令的输出,我将得到以下代码,该代码也可以工作:
for n in ['a','b','c','d']:
for m in ['e','f','g','h']:
print(m)
print(n)
fig, ax = plt.subplots(1,1, figsize=(5,5))
maxTimes=df2[n].idxmax()
PlottableTimes=maxTimes.dropna()
smap=plt.scatter(df2[n].max(), df2[m].max(), s=160,
c=[736809.0, 736810.0, 736811.0, 736812.0, 736813.0, 736814.0, 736815.0, 736816.0],
marker='.')
cb = fig.colorbar(smap, orientation='vertical',
format=DateFormatter('%d %b %y'))
plt.show()
但是,如果我将c =数组缩短一些,以模仿从idxmax删除NaN时代码中发生的情况,则会产生与我看到的相同的错误:
for n in ['a','b','c','d']:
for m in ['e','f','g','h']:
print(m)
print(n)
fig, ax = plt.subplots(1,1, figsize=(5,5))
maxTimes=df2[n].idxmax()
PlottableTimes=maxTimes.dropna()
smap=plt.scatter(df2[n].max(), df2[m].max(), s=160,
c=[736809.0, 736810.0, 736811.0, 736812.0, 736813.0, 736814.0],
marker='.')
cb = fig.colorbar(smap, orientation='vertical',
format=DateFormatter('%d %b %y'))
plt.show()
因此,这意味着真正的问题是:当所有列似乎都无法使用df2.col进行抓取时,如何从groupby对象进行分组之后如何抓取grouper列?我希望能够从以下内容中获取'ts'并将其用作颜色数据,而不是使用idxmax:
df2['a'].max()
ts
2018-01-01 9
2018-01-02 9
2018-01-03 9
2018-01-04 9
2018-01-05 9
2018-01-06 9
2018-01-07 9
2018-01-08 8
Freq: D, Name: a, dtype: int64
答案 0 :(得分:0)
从本质上讲,您的 Grouper 调用类似于在日期时间列上建立索引并调用pandas.DataFrame.resample
,以指定聚合函数:
df.set_index('ts').resample('D').max()
# a b c d e f g h
# ts
# 2018-01-01 9 9 8 9 9 9 9 9
# 2018-01-02 9 9 9 9 9 9 9 9
# 2018-01-03 9 9 9 9 9 9 9 9
# 2018-01-04 9 9 9 9 9 9 9 9
# 2018-01-05 9 9 9 9 9 9 9 9
# 2018-01-06 9 9 9 8 9 9 9 9
# 2018-01-07 9 9 9 9 9 9 9 9
# 2018-01-08 2 8 6 3 1 3 2 7
因此,df2['a'].max()
的返回是一个Pandas Resampler对象,与Pandas Series非常相似,因此带有index属性,可用于指定彩条:
df['a'].max().index
# DatetimeIndex(['2018-01-01', '2018-01-02', '2018-01-03', '2018-01-04',
# '2018-01-05', '2018-01-06', '2018-01-07', '2018-01-08'],
# dtype='datetime64[ns]', name='ts', freq='D')
从那里可以进入date2num
,而不列表理解:
date2num(df2['a'].max().index)
# array([736695., 736696., 736697., 736698., 736699., 736700., 736701., 736702.])
总而言之,只需在循环中使用以上内容,而无需 maxTimes 或 PlottableTimes :
fig, ax = plt.subplots(1, 1, figsize = (5,5))
smap = plt.scatter(df2[n].max(), df2[m].max(), s = 160,
c = date2num(df2[n].max().index),
marker = '.')
cb = fig.colorbar(smap, orientation = 'vertical',
format = DateFormatter('%d %b %y'))