在Python和matplotlib一个三维散点图绘制两个点之间的矩形或条形(Drawing a r

2019-09-17 06:25发布

我有一个3D散点图其中,在它的飞机之一,地块2点,每个日期。 我问过关于如何绘制每对点之间的线路 ,并收到了,我很感激一个答案。 我现在想的是画一个酒吧或矩形的点连接,而不只是一条线。

这里的情节是什么样子的时刻,但我希望它看起来有点像从情节从matplolib的文档3D酒吧演示除与酒吧“浮动”,而不是固定在轴上。

我已经尝试使用Axes3D.bar (如matplotlib页的说明),但它要求我提供一个“高度”每个条,而不是两个实际坐标,而高度将被固定在轴上。

这是代码,任何帮助表示赞赏。

import matplotlib.pyplot
from mpl_toolkits.mplot3d import Axes3D

dates       = [20020514, 20020515, 20020516, 20020517, 20020520]
highs       = [1135, 1158, 1152, 1158, 1163]
lows        = [1257, 1253, 1259, 1264, 1252]
upperLimits = [1125.0, 1125.0, 1093.75, 1125.0, 1125.0]
lowerLimits = [1250.0, 1250.0, 1156.25, 1250.0, 1250.0]

zaxisvalues0= [0, 0, 0, 0, 0]
zaxisvalues1= [1, 1, 1, 1, 1]
zaxisvalues2= [2, 2, 2, 2, 2]

fig = matplotlib.pyplot.figure()
ax  = fig.add_subplot(111, projection = '3d')

ax.plot(dates, zaxisvalues1, lowerLimits, color = 'b')
ax.plot(dates, zaxisvalues2, upperLimits, color = 'r')

for i,j,k,h in zip(dates,zaxisvalues0,lows,highs):
    ax.plot([i,i],[j,j],[k,h],color = 'g')

ax.scatter(dates, zaxisvalues0, highs, color = 'g', marker = "o")
ax.scatter(dates, zaxisvalues0, lows, color = 'y', marker = "^")

matplotlib.pyplot.show()

Answer 1:

我认为这将是更容易使用PolyCollection。 这是接近你所追求的?

import matplotlib.pyplot
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.collections import PolyCollection
import random

dates       = [20020514, 20020515, 20020516, 20020517, 20020520]
highs       = [1135, 1158, 1152, 1158, 1163]
lows        = [1257, 1253, 1259, 1264, 1252]
upperLimits = [1125.0, 1125.0, 1093.75, 1125.0, 1125.0]
lowerLimits = [1250.0, 1250.0, 1156.25, 1250.0, 1250.0]

zaxisvalues0= [0, 0, 0, 0, 0]
zaxisvalues1= [1, 1, 1, 1, 1]
zaxisvalues2= [2, 2, 2, 2, 2]

fig = matplotlib.pyplot.figure()
ax  = fig.add_subplot(111, projection = '3d')

ax.plot(dates, zaxisvalues1, lowerLimits, color = 'b')
ax.plot(dates, zaxisvalues2, upperLimits, color = 'r')

verts = []; fcs = []
for i in range(len(dates)-1):
   xs = [dates[i],dates[i+1],dates[i+1],dates[i],dates[i]] # each box has 4 vertices, give it 5 to close it, these are the x coordinates
   ys = [highs[i],highs[i+1],lows[i+1],lows[i], highs[i]]  # each box has 4 vertices, give it 5 to close it, these are the y coordinates
   verts.append(zip(xs,ys))
   fcs.append((random.random(),random.random(),random.random(),0.6))

poly = PolyCollection(verts, facecolors = fcs, closed = False)
ax.add_collection3d(poly, zs=[zaxisvalues0[0]] * len(verts), zdir='y') # in the "z" just use the same coordinate

ax.scatter(dates, zaxisvalues0, highs, color = 'g', marker = "o")
ax.scatter(dates, zaxisvalues0, lows, color = 'y', marker = "^")

matplotlib.pyplot.show()


Answer 2:

你应该能够作出之间的混合:

从matplolib的文档3D演示吧

酒吧层叠例

即绘制酒吧在3D图形,但使用“底部”参数来设置栏的起点唤起注意。

亚历克西斯



Answer 3:

感谢您的帮助亚历克西斯和马克。 我认为它现在整理出来。

我用Alexis的提示使用‘zdir’属性。

至于错飞机的问题,你可以用参数zdir修复它,例如ax.bar(日期,高开低走,zdir = 'Y',底部=高点,ZS = 0,颜色= 'B') - 亚历克西斯

起初它被生成的两倍高,因为他们应该是棒,因为它是从底部测量(即“低”的值),然后添加到其上的高度(从“高”值)。

所以最后我介绍一个新的列表,“位移”,其测量每个高和低的每个之间的距离(在过程中发现,我有我的低音和高音换各地。咄,我们对此深感抱歉)。 所以现在我策划“位移”,而不是高位。

我加入到Alexis的线的宽度,对齐edgecolor和alpha(透明度); 然后增厚的ax.scatter地块标记。 现在的代码工作(当然,差不多,除4条是对箭头高于它应该是...嗯)

import matplotlib.pyplot
from mpl_toolkits.mplot3d import Axes3D

dates       = [20020514, 20020515, 20020516, 20020517, 20020520]
lows        = [1135, 1158, 1152, 1158, 1163]
highs       = [1257, 1253, 1259, 1264, 1252]
upperLimits = [1125.0, 1125.0, 1093.75, 1125.0, 1125.0]
lowerLimits = [1250.0, 1250.0, 1156.25, 1250.0, 1250.0]

zaxisvalues0= [0, 0, 0, 0, 0]
zaxisvalues1= [1, 1, 1, 1, 1]
zaxisvalues2= [2, 2, 2, 2, 2]

fig = matplotlib.pyplot.figure()
ax  = fig.add_subplot(111, projection = '3d')

ax.plot(dates, zaxisvalues1, lowerLimits, color = 'b')
ax.plot(dates, zaxisvalues2, upperLimits, color = 'r')

ax.scatter(dates, zaxisvalues0, highs, color = 'g', marker = "^", linewidth=4)
ax.scatter(dates, zaxisvalues0, lows,  color = 'y', marker = "o", linewidth=4)

displacements = []
for i in lows:
    position = lows.index(i)
    disp = highs[position] - i
    displacements.append(disp)

ax.bar(dates, displacements, zdir='y', bottom=lows, zs=0, width=0.2, align='center', alpha=0.6, edgecolor='k')

matplotlib.pyplot.show()

这是结果:



文章来源: Drawing a rectangle or bar between two points in a 3D scatter plot in Python and matplotlib