Python matplotlib:如何在打印中使用标记大小/颜色作为额外尺寸?
我正在绘制一个时间序列,其中Python matplotlib:如何在打印中使用标记大小/颜色作为额外尺寸?,python,datetime,matplotlib,Python,Datetime,Matplotlib,我正在绘制一个时间序列,其中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(使用正确的勾号标签),
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
(使用正确的勾号标签),则只能一次为所有点设置markersize/color,即无法将它们映射到额外的序列
既然scatter
和plot
都能完成我所需的一半,那么有什么方法可以同时做到这两个呢
UPDATE在的问题之后,我意识到scatter
在default\u units()
的matplotlib/dates.py
行中提出了一个KeyError
:
x = x[0]
可以肯定的是,myx
和y
都是从索引中没有“0”的pandas数据帧中获取的序列。然后我尝试了两件事(都觉得有点不舒服):
首先,我尝试将数据帧索引修改为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可以接受任何类似数组的输入,但显然,如果数据不是需要一些内部操作的简单数字,那么这并不完全正确
更新2我也试着按照的建议去做(顺便说一句,谢谢你的编辑技巧)。如果我理解正确,我首先将x
转换为一系列“matplotlib风格的日子”:
mx = mPlotDATEs.date2num(list(x))
这样我就可以直接呼叫:
scatter(mx, y, s=z)
然后,为了正确标记轴,我调用:
gca().xaxis.set_major_formatter( DateFormatter('%Y-%m-%d %H:%M'))
(在交互模式下,调用show()
更新轴标签)
它工作得很好,给我的感觉是一种更“合适”的做事方式,因此我将接受这一最佳答案。您可能可以将x
中的对象从datetime.datertime
转换为int
(从1970年开始以秒表示)
然后将其传递给scatter
scatter(x, y, s=z, c=w)
你也许可以试试for循环。这是一个相对较好的选择,只要您没有太多的数据来绘制。下面我写一个小例子:
import numpy as np
import matplotlib.pyplot as plt
x = np.random.rand(100)
y = np.random.rand(100)
mass = np.linspace(1,10,100)
for i in xrange(len(x)):
plt.plot(x[i],y[i],'ko', markersize=mass[i])
plt.show()
原则上你也可以用同样的颜色 有办法做到这两个吗?对
但是,让我们通过示例来工作:
步骤A:从datetime
到matplotlib
约定-兼容
日期/时间
步骤B:添加3D
4D
5D
功能(使用附加的{颜色
大小
}--信息的编码维度)
像往常一样,魔鬼被隐藏在细节中
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.
因此,强烈建议重新使用他们自己的工具:
管理轴标签、格式和比例(最小/最大)是一个单独的问题
然而,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
中还有其他工具,包括一套针对各种特定领域或人眼视觉/感知适应色标度的着色。对色阶/归一化定标器给出了一个很好的解释
您可能已经注意到,这个4D
示例仍然有一个常量alpha
(未用于真实5D
维度可视化中的第五个DOF)您是否可以提出一个问题,散射应该与单元框架一起工作。它引起了什么错误?@tcaswell现在你问了,我回去后注意到scatter
引起了一个“KeyError”,至少部分原因是x
(和y
)是一个熊猫系列。我将更新我的问题以反映这一点。内部体操是一个了不起的观点:o)
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'
)
#------------------------------------------------------------------