matplotlib 无法绘制彩色希尔伯特曲线?
matplotlib can't plot colored Hilbert curve?
我正在尝试绘制彩色 2D Hilbert curve using matplotlib. After getting the x
and y
coordinates, a plain ax.plot(x,y)
gives the correct curve, but if I want to color-code the curve using the technique introduced in this post,它给了我一个空的 canvas(因此未显示)。
奇怪的是,原始答案中显示的随机路径有效。
我的代码如下:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.collections as mcoll
import matplotlib.path as mpath
def xy2d(n,x,y):
d=0
s=n/2
while s>0:
rx=(x&s)>0
ry=(y&s)>0
d+=s*s*((3*rx)^ry)
s,x,y,rx,ry=rot(s,x,y,rx,ry)
s/=2
return d
def d2xy(n,d):
t=d
x=y=0
s=1
while s<n:
rx=1&(t/2)
ry=1&(t^rx)
s,x,y,rx,ry=rot(s,x,y,rx,ry)
x+=s*rx
y+=s*ry
t/=4
s*=2
return x,y
def rot(n,x,y,rx,ry):
if ry==0:
if rx==1:
x=n-1-x
y=n-1-y
x,y=y,x
return n,x,y,rx,ry
#--------------These are copied from SO--------------
def colorline(
x, y, z=None, ax=None, cmap=plt.get_cmap('copper'), norm=plt.Normalize(0.0, 1.0),
linewidth=3, alpha=1.0):
"""
http://nbviewer.ipython.org/github/dpsanders/matplotlib-examples/blob/master/colorline.ipynb
http://matplotlib.org/examples/pylab_examples/multicolored_line.html
Plot a colored line with coordinates x and y
Optionally specify colors in the array z
Optionally specify a colormap, a norm function and a line width
"""
# Default colors equally spaced on [0,1]:
if z is None:
z = np.linspace(0.0, 1.0, len(x))
# Special case if a single number:
if not hasattr(z, "__iter__"): # to check for numerical input -- this is a hack
z = np.array([z])
z = np.asarray(z)
segments = make_segments(x, y)
lc = mcoll.LineCollection(segments, array=z, cmap=cmap, norm=norm,
linewidth=linewidth, alpha=alpha)
if ax is None:
ax = plt.gca()
ax.add_collection(lc)
return lc
def make_segments(x, y):
"""
Create list of line segments from x and y coordinates, in the correct format
for LineCollection: an array of the form numlines x (points per line) x 2 (x
and y) array
"""
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
return segments
#--------------These are copied from SO--------------
if __name__=='__main__':
xs=[]
ys=[]
N=16
for i in range(N**2-1):
x,y=d2xy(N,i)
xs.append(x)
ys.append(y)
#-------------------Plot------------------------
figure=plt.figure(figsize=(12,10),dpi=100)
cmap=plt.cm.jet
ax=figure.add_subplot(111)
path = mpath.Path(np.column_stack([xs, ys]))
#verts = path.interpolated(steps=1).vertices
verts=path.vertices
x, y = verts[:, 0], verts[:, 1]
z = np.linspace(0, 1, len(xs))
colorline(x, y, z, ax=ax, cmap=cmap, linewidth=1)
#ax.plot(x,y) # this works, but with blue line
plt.show(block=False)
我是不是遗漏了什么明显的东西?
我的设置:
- python=2.7.14,在蟒蛇 4.4.10
- matplotlib=2.0.2=py27h334a7c2_1,也测试了2.1.2=py27h0e671d2_0
- numpy=1.14.1
代码有效,但是两个轴限制都是 (0,1)
,因此您放大得太大而看不到绘图。似乎 add_collection
不会自动缩放坐标轴。
解决方法是简单地自己缩放坐标轴:
ax.set_ylim(0,15)
ax.set_xlim(0,15)
# or use plt.xlim() if not using object oriented API
我正在尝试绘制彩色 2D Hilbert curve using matplotlib. After getting the x
and y
coordinates, a plain ax.plot(x,y)
gives the correct curve, but if I want to color-code the curve using the technique introduced in this post,它给了我一个空的 canvas(因此未显示)。
奇怪的是,原始答案中显示的随机路径有效。
我的代码如下:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.collections as mcoll
import matplotlib.path as mpath
def xy2d(n,x,y):
d=0
s=n/2
while s>0:
rx=(x&s)>0
ry=(y&s)>0
d+=s*s*((3*rx)^ry)
s,x,y,rx,ry=rot(s,x,y,rx,ry)
s/=2
return d
def d2xy(n,d):
t=d
x=y=0
s=1
while s<n:
rx=1&(t/2)
ry=1&(t^rx)
s,x,y,rx,ry=rot(s,x,y,rx,ry)
x+=s*rx
y+=s*ry
t/=4
s*=2
return x,y
def rot(n,x,y,rx,ry):
if ry==0:
if rx==1:
x=n-1-x
y=n-1-y
x,y=y,x
return n,x,y,rx,ry
#--------------These are copied from SO--------------
def colorline(
x, y, z=None, ax=None, cmap=plt.get_cmap('copper'), norm=plt.Normalize(0.0, 1.0),
linewidth=3, alpha=1.0):
"""
http://nbviewer.ipython.org/github/dpsanders/matplotlib-examples/blob/master/colorline.ipynb
http://matplotlib.org/examples/pylab_examples/multicolored_line.html
Plot a colored line with coordinates x and y
Optionally specify colors in the array z
Optionally specify a colormap, a norm function and a line width
"""
# Default colors equally spaced on [0,1]:
if z is None:
z = np.linspace(0.0, 1.0, len(x))
# Special case if a single number:
if not hasattr(z, "__iter__"): # to check for numerical input -- this is a hack
z = np.array([z])
z = np.asarray(z)
segments = make_segments(x, y)
lc = mcoll.LineCollection(segments, array=z, cmap=cmap, norm=norm,
linewidth=linewidth, alpha=alpha)
if ax is None:
ax = plt.gca()
ax.add_collection(lc)
return lc
def make_segments(x, y):
"""
Create list of line segments from x and y coordinates, in the correct format
for LineCollection: an array of the form numlines x (points per line) x 2 (x
and y) array
"""
points = np.array([x, y]).T.reshape(-1, 1, 2)
segments = np.concatenate([points[:-1], points[1:]], axis=1)
return segments
#--------------These are copied from SO--------------
if __name__=='__main__':
xs=[]
ys=[]
N=16
for i in range(N**2-1):
x,y=d2xy(N,i)
xs.append(x)
ys.append(y)
#-------------------Plot------------------------
figure=plt.figure(figsize=(12,10),dpi=100)
cmap=plt.cm.jet
ax=figure.add_subplot(111)
path = mpath.Path(np.column_stack([xs, ys]))
#verts = path.interpolated(steps=1).vertices
verts=path.vertices
x, y = verts[:, 0], verts[:, 1]
z = np.linspace(0, 1, len(xs))
colorline(x, y, z, ax=ax, cmap=cmap, linewidth=1)
#ax.plot(x,y) # this works, but with blue line
plt.show(block=False)
我是不是遗漏了什么明显的东西?
我的设置:
- python=2.7.14,在蟒蛇 4.4.10
- matplotlib=2.0.2=py27h334a7c2_1,也测试了2.1.2=py27h0e671d2_0
- numpy=1.14.1
代码有效,但是两个轴限制都是 (0,1)
,因此您放大得太大而看不到绘图。似乎 add_collection
不会自动缩放坐标轴。
解决方法是简单地自己缩放坐标轴:
ax.set_ylim(0,15)
ax.set_xlim(0,15)
# or use plt.xlim() if not using object oriented API