1

I'm trying to plot a colored 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, it gives me an empty canvas (so not shown).

Strangely, the random path as shown in the original answer works.

My code below:

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)

Am I missing something obvious?

My setup:

  • python=2.7.14, in anaconda 4.4.10
  • matplotlib=2.0.2=py27h334a7c2_1, also tested 2.1.2=py27h0e671d2_0
  • numpy=1.14.1
3
  • You need to set your axis limits Commented Mar 8, 2018 at 13:29
  • @DavidG Indeed! So add_collection() actually doesn't trigger an automatic limit setting. Commented Mar 8, 2018 at 13:34
  • You need to autoscale the plot manually. See duplicate. Commented Mar 8, 2018 at 14:02

1 Answer 1

1

The code is working, however both the axis limits are (0,1), therefore you're too zoomed in to see the plot. It seems that add_collection doesn't auto scale the axes.

The solution is to simply scale the axes yourself:

ax.set_ylim(0,15)
ax.set_xlim(0,15)

# or use plt.xlim() if not using object oriented API
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.