我想在gnuplot
中为一系列曲线添加箭头。问题是如何将箭头放在曲线的中心。我的解决方案是在点序列中找到线段,并为该线段绘制一个箭头。它有效,但箭头的大小不同。
我已经用python + gnuplot编写了一个代码,但它看起来很丑陋
#!/bin/python
import numpy as np
import Gnuplot
def middleArrowCurve(g, x,y, percent, reverse=False):
d = Gnuplot.Data(x,y,with_='l')
index = int(len(x)*percent)
fromx,tox = x[index],x[index+1]
fromy,toy = y[index],y[index+1]
g('set style arrow 1 front head filled size screen 0.03,15 lt 1 lw 1')
if reverse:
g('set arrow from ' + str(tox) + ',' + str(toy) + ' to ' + str(fromx) + ',' + str(fromy) + ' as 1')
else :
g('set arrow from ' + str(fromx) + ',' + str(fromy) + ' to ' + str(tox) + ',' + str(toy) + ' as 1')
return d
def stableNode2():
g = Gnuplot.Gnuplot(persist=1)
g('set term png')
g('set output "stableNode2.png"')
g('unset key')
g('unset tics')
g('unset border')
g('set xrange [-1:1]')
g('set yrange [-1:1]')
data = []
reverse = False
for s in [-1,1]:
x = np.linspace(s,0,20)
data.append(middleArrowCurve(g,x,0.6*x**2,0.5,reverse))
data.append(middleArrowCurve(g,x,-0.6*x**2,0.5,reverse))
data.append(middleArrowCurve(g,x,2*x**2,0.5,reverse))
data.append(middleArrowCurve(g,x,-2*x**2,0.5,reverse))
data.append(middleArrowCurve(g,x,x*0,0.5,reverse))
data.append(middleArrowCurve(g,x*0,x,0.5,reverse))
g.plot(*data)
stableNode2()
答案 0 :(得分:2)
从版本4.6开始,如果箭头长度小于头部长度的两倍,gnuplot会自动缩放箭头。在5.0版本中(几乎稳定,5.0RC2已经用完),引入了一个额外的箭头参数fixed
来防止这种缩放。所以使用
g('set style arrow 1 front head filled size screen 0.03,15 fixed lt 1 lw 1')
给出了结果:
在版本4.6中,我不知道任何其他解决方法,而不是增加某些箭头的长度。
答案 1 :(得分:1)
使用set object poly
可以解决此问题。
#!/bin/python
import numpy as np
import Gnuplot
arrowCount = 0
def addArrow(g, x,y, dx, dy, width=0.01,angle=15):
def normal(v):
s = 1.0/np.sqrt(v[0]**2+v[1]**2)
v[0] *= s
v[1] *= s
l = [dx,dy]
n = [-dy,dx]
normal(l)
normal(n)
length = width/np.tan(angle*np.pi/360)
coords = []
coords.append((x,y))
coords.append((x+n[0]*width,y+n[1]*width))
coords.append((x+l[0]*length,y+l[1]*length))
coords.append((x-n[0]*width,y-n[1]*width))
coords.append((x,y))
coordsStr = "from "
coordsStr += " to ".join([str(c[0])+","+str(c[1]) for c in coords])
global arrowCount
arrowCount += 1
return 'set object ' + str(arrowCount) + ' polygon ' + coordsStr + ';set object ' + str(arrowCount) + ' fc rgb "red" fs solid '
def middleArrowCurve(g, x,y, percent, reverse=False):
d = Gnuplot.Data(x,y,with_='l')
index = int(len(x)*percent)
fromx,tox = x[index],x[index+1]
fromy,toy = y[index],y[index+1]
if reverse:
return d,addArrow(g, tox,toy, -tox+fromx, -toy+fromy)
else:
return d,addArrow(g, fromx,fromy, tox-fromx, toy-fromy)
def stableNode2():
g = Gnuplot.Gnuplot(persist=1)
g('set term png')
g('set output "stableNode2.png"')
g('unset key')
g('unset tics')
g('unset border')
g('set xrange [-1:1]')
g('set yrange [-1:1]')
data = []
reverse = False
for s in [-1,1]:
x = np.linspace(s,0,20)
data.append(middleArrowCurve(g,x,0.6*x**2,0.5,reverse))
data.append(middleArrowCurve(g,x,-0.6*x**2,0.5,reverse))
data.append(middleArrowCurve(g,x,2*x**2,0.5,reverse))
data.append(middleArrowCurve(g,x,-2*x**2,0.5,reverse))
data.append(middleArrowCurve(g,x,x*0,0.5,reverse))
data.append(middleArrowCurve(g,x*0,x,0.5,reverse))
for a in data:
g(a[1])
g.plot(*[d[0] for d in data])
stableNode2()
剩下的问题是多边形箭头被线图覆盖的原因?如果我在线图之后放置多边形绘图,则只会忽略它们。