我正在绘制一个时间序列,其中x
是一系列 datetime.datetime
对象,y
是一系列双打。
我想将标记大小映射到第三个系列z
(并且还可能将标记颜色映射到第四个系列w
),这在大多数情况下可以通过以下方式完成:
scatter(x, y, s=z, c=w)
除了 scatter()
不允许x
成为一系列datetime.datetime
个对象。
plot(x, y, marker='o', linestyle='None')
另一方面,使用x
为datetime.datetime
(带有正确的刻度标签),但只能为所有点设置markerize / color,即无法将它们映射到额外的系列
看到scatter
和plot
每个可以做我需要的一半,有两种方法可以做到吗?
更新在 @tcaswell 的问题之后,我意识到scatter
在{KeyError
深了default_units()
1}}在matplotlib/dates.py
的行中:
x = x[0]
果然,我的x
和y
都是从大熊猫DataFrame获取的系列,没有' 0'在索引中。然后我尝试了两件事(都觉得有点hacky):
首先,我尝试将DataFrame索引修改为0..len(x)
,这导致matplotlib/axes/_axes.py
内的不同错误:
offsets = np.dstack((x,y))
dstack
与熊猫系列并不好玩。所以我尝试将x
和y
转换为numpy.array:
scatter(numpy.array(x), numpy.array(y), s=numpy.array(z))
这几乎有效,除了散射似乎无法自动缩放x
轴并将所有内容折叠成一条直线,因此我必须明确重置xlim
才能看到该情节。
所有这一切都是说scatter
可以完成这项工作,尽管有点卷积。我一直认为matplotlib可以接受任何类似数组的输入,但显然如果数据不是需要一些内部体操的简单数字则不完全正确。
UPDATE2 我还尝试按照 @user3666197 的建议(感谢btw的编辑提示)。如果我理解正确,我首先将x
转换为一系列matplotlib风格的日子':
mx = mPlotDATEs.date2num(list(x))
然后允许我直接打电话:
scatter(mx, y, s=z)
然后正确地标记轴,我打电话:
gca().xaxis.set_major_formatter( DateFormatter('%Y-%m-%d %H:%M'))
(如果是交互模式,请调用show()
更新轴标签)
它工作得非常好,并且对我来说是一个更合适的'做事的方式,所以我会接受这个作为最好的答案。
答案 0 :(得分:3)
但是,让我们举例说明:
步骤A :从datetime
到matplotlib
惯例 - 兼容 float
日期/时间
第B步:添加 3D
| 4D
| 5D
功能(使用其他{color
| size
| alpha
} - 信息的编码维度)
像往常一样, devil 会被隐藏起来。
matplotlib
日期 几乎 相等,但不等于:
# mPlotDATEs.date2num.__doc__
#
# *d* is either a class `datetime` instance or a sequence of datetimes.
#
# Return value is a floating point number (or sequence of floats)
# which gives the number of days (fraction part represents hours,
# minutes, seconds) since 0001-01-01 00:00:00 UTC, *plus* *one*.
# The addition of one here is a historical artifact. Also, note
# that the Gregorian calendar is assumed; this is not universal
# practice. For details, see the module docstring.
因此,强烈建议重新使用他们自己的"工具:
from matplotlib import dates as mPlotDATEs # helper functions num2date()
# # and date2num()
# # to convert to/from.
尽管如此,matplotlib也为这部分带来了武器:
from matplotlib.dates import DateFormatter, \
AutoDateLocator, \
HourLocator, \
MinuteLocator, \
epoch2num
from matplotlib.ticker import ScalarFormatter, FuncFormatter
并且可以例如:
aPlotAX.set_xlim( x_min, x_MAX ) # X-AXIS LIMITs ------------------------------------------------------------------------------- X-LIMITs
#lt.gca().xaxis.set_major_locator( matplotlib.ticker.FixedLocator( secs ) )
#lt.gca().xaxis.set_major_formatter( matplotlib.ticker.FuncFormatter( lambda pos, _: time.strftime( "%d-%m-%Y %H:%M:%S", time.localtime( pos ) ) ) )
aPlotAX.xaxis.set_major_locator( AutoDateLocator() )
aPlotAX.xaxis.set_major_formatter( DateFormatter( '%Y-%m-%d %H:%M' ) ) # ----------------------------------------------------------------------------------------- X-FORMAT
#--------------------------------------------- # 90-deg x-tick-LABELs
plt.setp( plt.gca().get_xticklabels(), rotation = 90,
horizontalalignment = 'right'
)
#------------------------------------------------------------------
3D
| 4D
| 5D
}转码想象一下这种方法,请查看此示例,
使用不同的工具将信息的附加维度编码到{color
|中size
| alpha
}。而{size
| alpha
}与散点相关,color
matplotlib
中还有其他工具,其中包含一组着色,适用于各种特定领域或人眼视觉/感知的色阶。对色阶/标准化缩放器的一个很好的解释是 here
答案 1 :(得分:1)
您可以将x
中的对象从datetime.datertime
转换为int
(通过自1970年代以来的秒数表示)
import time
x = [time.mktime(elem.timetuple()) for elem in x]
然后将其传递给scatter
scatter(x, y, s=z, c=w)
答案 2 :(得分:1)