Exemple #1
0
def MeshPoints(*inputobj, **options):
    """
    Build a point object of type ``Mesh`` for a list of points.

    :param float r: point radius.
    :param c: color name, number, or list of [R,G,B] colors of same length as plist.
    :type c: int, str, list
    :param float alpha: transparency in range [0,1].
    """
    r = options.pop("r", 5)
    c = options.pop("c", "gray")
    alpha = options.pop("alpha", 1)

    mesh, u = _inputsort(inputobj)
    if not mesh:
        return None

    if hasattr(mesh, "coordinates"):
        plist = mesh.coordinates()
    else:
        plist = mesh.geometry.points

    u_values = _compute_uvalues(u, mesh)

    if len(plist[0]) == 2:  # coords are 2d.. not good..
        plist = np.insert(plist, 2, 0, axis=1)  # make it 3d
    if len(plist[0]) == 1:  # coords are 1d.. not good..
        plist = np.insert(plist, 1, 0, axis=1)  # make it 3d
        plist = np.insert(plist, 2, 0, axis=1)

    actor = shapes.Points(plist, r=r, c=c, alpha=alpha)

    actor.mesh = mesh
    if u:
        actor.u = u
        if len(u_values.shape) == 2:
            if u_values.shape[1] in [2, 3]:  # u_values is 2D or 3D
                actor.u_values = u_values
                dispsizes = utils.mag(u_values)
        else:  # u_values is 1D
            dispsizes = u_values
        actor.addPointScalars(dispsizes, "u_values")
    return actor
Exemple #2
0
def fxy(
        z="sin(3*x)*log(x-y)/3",
        x=(0, 3),
        y=(0, 3),
        zlimits=(None, None),
        showNan=True,
        zlevels=10,
        c="b",
        bc="aqua",
        alpha=1,
        texture="paper",
        res=(100, 100),
):
    """
    Build a surface representing the function :math:`f(x,y)` specified as a string
    or as a reference to an external function.

    :param float x: x range of values.
    :param float y: y range of values.
    :param float zlimits: limit the z range of the independent variable.
    :param int zlevels: will draw the specified number of z-levels contour lines.
    :param bool showNan: show where the function does not exist as red points.
    :param list res: resolution in x and y.

    |fxy| |fxy.py|_

        Function is: :math:`f(x,y)=\sin(3x) \cdot \log(x-y)/3` in range :math:`x=[0,3], y=[0,3]`.
    """
    if isinstance(z, str):
        try:
            z = z.replace("math.", "").replace("np.", "")
            namespace = locals()
            code = "from math import*\ndef zfunc(x,y): return " + z
            exec(code, namespace)
            z = namespace["zfunc"]
        except:
            colors.printc("Syntax Error in fxy()", c=1)
            return None

    ps = vtk.vtkPlaneSource()
    ps.SetResolution(res[0], res[1])
    ps.SetNormal([0, 0, 1])
    ps.Update()
    poly = ps.GetOutput()
    dx = x[1] - x[0]
    dy = y[1] - y[0]
    todel, nans = [], []

    for i in range(poly.GetNumberOfPoints()):
        px, py, _ = poly.GetPoint(i)
        xv = (px + 0.5) * dx + x[0]
        yv = (py + 0.5) * dy + y[0]
        try:
            zv = z(xv, yv)
        except:
            zv = 0
            todel.append(i)
            nans.append([xv, yv, 0])
        poly.GetPoints().SetPoint(i, [xv, yv, zv])

    if len(todel):
        cellIds = vtk.vtkIdList()
        poly.BuildLinks()
        for i in todel:
            poly.GetPointCells(i, cellIds)
            for j in range(cellIds.GetNumberOfIds()):
                poly.DeleteCell(cellIds.GetId(j))  # flag cell
        poly.RemoveDeletedCells()
        cl = vtk.vtkCleanPolyData()
        cl.SetInputData(poly)
        cl.Update()
        poly = cl.GetOutput()

    if not poly.GetNumberOfPoints():
        colors.printc("Function is not real in the domain", c=1)
        return None

    if zlimits[0]:
        tmpact1 = Actor(poly)
        a = tmpact1.cutWithPlane((0, 0, zlimits[0]), (0, 0, 1))
        poly = a.polydata()
    if zlimits[1]:
        tmpact2 = Actor(poly)
        a = tmpact2.cutWithPlane((0, 0, zlimits[1]), (0, 0, -1))
        poly = a.polydata()

    if c is None:
        elev = vtk.vtkElevationFilter()
        elev.SetInputData(poly)
        elev.Update()
        poly = elev.GetOutput()

    actor = Actor(poly, c, alpha).computeNormals().lighting("plastic")
    if c is None:
        actor.scalars("Elevation")

    if bc:
        actor.bc(bc)

    actor.texture(texture)

    acts = [actor]
    if zlevels:
        elevation = vtk.vtkElevationFilter()
        elevation.SetInputData(poly)
        bounds = poly.GetBounds()
        elevation.SetLowPoint(0, 0, bounds[4])
        elevation.SetHighPoint(0, 0, bounds[5])
        elevation.Update()
        bcf = vtk.vtkBandedPolyDataContourFilter()
        bcf.SetInputData(elevation.GetOutput())
        bcf.SetScalarModeToValue()
        bcf.GenerateContourEdgesOn()
        bcf.GenerateValues(zlevels, elevation.GetScalarRange())
        bcf.Update()
        zpoly = bcf.GetContourEdgesOutput()
        zbandsact = Actor(zpoly, "k", alpha).lw(0.5)
        acts.append(zbandsact)

    if showNan and len(todel):
        bb = actor.GetBounds()
        if bb[4] <= 0 and bb[5] >= 0:
            zm = 0.0
        else:
            zm = (bb[4] + bb[5]) / 2
        nans = np.array(nans) + [0, 0, zm]
        nansact = shapes.Points(nans, r=2, c="red", alpha=alpha)
        nansact.GetProperty().RenderPointsAsSpheresOff()
        acts.append(nansact)

    if len(acts) > 1:
        return Assembly(acts)
    else:
        return actor
Exemple #3
0
def plotxy(
    data,
    xerrors=None,
    yerrors=None,
    xlimits=None,
    ylimits=None,
    xscale=1,
    yscale=None,
    xlogscale=False,
    ylogscale=False,
    c="k",
    alpha=1,
    xtitle="x",
    ytitle="y",
    title="",
    titleSize=None,
    ec=None,
    lc="k",
    lw=2,
    line=True,
    dashed=False,
    splined=False,
    marker=None,
    ms=None,
    mc=None,
    ma=None,
):
    """Draw a 2D plot of variable x vs y.

    :param list data: input format can be [allx, ally] or [(x1,y1), (x2,y2), ...]

    :param list xerrors: set uncertainties for the x variable, shown as error bars.
    :param list yerrors: set uncertainties for the y variable, shown as error bars.
    :param list xlimits: set limits to the range for the x variable
    :param list ylimits: set limits to the range for the y variable
    :param float xscale: set scaling factor in x. Default is 1.
    :param float yscale: set scaling factor in y. Automatically calculated to get
        a reasonable aspect ratio. Scaling factor is saved in `info['yscale']`.

    :param bool xlogscale: set x logarithmic scale.
    :param bool ylogscale: set y logarithmic scale.
    :param str c: color of frame and text.
    :param float alpha: opacity of frame and text.
    :param str xtitle: title label along x-axis.
    :param str ytitle: title label along y-axis.
    :param str title: histogram title on top.
    :param float titleSize: size of title
    :param str ec: color of error bar, by default the same as marker color
    :param str lc: color of line
    :param float lw: width of line
    :param bool line: join points with line
    :param bool dashed: use a dashed line style
    :param bool splined: spline the line joining the point as a countinous curve
    :param str,int marker: use a marker shape for the data points
    :param float ms: marker size.
    :param str mc: color of marker
    :param float ma: opacity of marker

    |plotxy| |plotxy.py|_
    """
    if len(data) == 2 and len(data[0]) > 1 and len(data[0]) == len(data[1]):
        #format is [allx, ally], convert it:
        data = np.c_[data[0], data[1]]

    if xlimits is not None:
        cdata = []
        x0lim = xlimits[0]
        x1lim = xlimits[1]
        for d in data:
            if d[0] > x0lim and d[0] < x1lim:
                cdata.append(d)
        data = cdata
        if not len(data):
            colors.printc("Error in plotxy(): no points within xlimits", c=1)
            return None

    if ylimits is not None:
        cdata = []
        y0lim = ylimits[0]
        y1lim = ylimits[1]
        for d in data:
            if d[1] > y0lim and d[1] < y1lim:
                cdata.append(d)
        data = cdata
        if not len(data):
            colors.printc("Error in plotxy(): no points within ylimits", c=1)
            return None

    data = np.array(data)[:, [0, 1]]

    if xlogscale:
        data[:, 0] = np.log(data[:, 0])

    if ylogscale:
        data[:, 1] = np.log(data[:, 1])

    x0, y0 = np.min(data, axis=0)
    x1, y1 = np.max(data, axis=0)

    if yscale is None:
        yscale = (x1 - x0) / (y1 - y0) * 0.75  # default 3/4 aspect ratio
        yscale = float(utils.precision(yscale, 1))
        if abs(yscale - 1) > 0.2:
            ytitle += " *" + str(yscale)
            y0 *= yscale
            y1 *= yscale
        else:
            yscale = 1

    scale = np.array([[xscale, yscale]])
    data = np.multiply(data, scale)

    acts = []
    if dashed:
        l = shapes.DashedLine(data, lw=lw, spacing=20)
        acts.append(l)
    elif splined:
        l = shapes.KSpline(data).lw(lw).c(lc)
        acts.append(l)
    elif line:
        l = shapes.Line(data, lw=lw, c=lc)
        acts.append(l)

    if marker:
        if ms is None:
            ms = (x1 - x0) / 75.0
        if mc is None:
            mc = lc
        mk = shapes.Marker(marker, s=ms, alpha=ma)
        pts = shapes.Points(data)
        marked = shapes.Glyph(pts, glyphObj=mk, c=mc)
        acts.append(marked)

    if ec is None:
        if mc is not None:
            ec = mc
        else:
            ec = lc
        offs = (x1 - x0) / 1000

    if yerrors is not None:
        if len(yerrors) != len(data):
            colors.printc(
                "Error in plotxy(yerrors=...): mismatched array length.", c=1)
            return None
        errs = []
        for i in range(len(data)):
            xval, yval = data[i]
            yerr = yerrors[i] / 2 * yscale
            errs.append(
                shapes.Line((xval, yval - yerr, offs),
                            (xval, yval + yerr, offs)))
        myerrs = merge(errs).c(ec).lw(lw).alpha(alpha)
        acts.append(myerrs)

    if xerrors is not None:
        if len(xerrors) != len(data):
            colors.printc(
                "Error in plotxy(xerrors=...): mismatched array length.", c=1)
            return None
        errs = []
        for i in range(len(data)):
            xval, yval = data[i]
            xerr = xerrors[i] / 2
            errs.append(
                shapes.Line((xval - xerr, yval, offs),
                            (xval + xerr, yval, offs)))
        mxerrs = merge(errs).c(ec).lw(lw).alpha(alpha)
        acts.append(mxerrs)

    x0lim = x0
    x1lim = x1
    y0lim = y0 * yscale
    y1lim = y1 * yscale
    if xlimits is not None or ylimits is not None:
        if xlimits is not None:
            x0lim = min(xlimits[0], x0)
            x1lim = max(xlimits[1], x1)
        if ylimits is not None:
            y0lim = min(ylimits[0] * yscale, y0)
            y1lim = max(ylimits[1] * yscale, y1)
        rec = shapes.Rectangle([x0lim, y0lim, 0], [x1lim, y1lim, 0])
        rec.alpha(0).wireframe()
        acts.append(rec)

    if title:
        if titleSize is None:
            titleSize = (x1lim - x0lim) / 40.0
        tit = shapes.Text(
            title,
            s=titleSize,
            c=c,
            depth=0,
            alpha=alpha,
            pos=((x1lim + x0lim) / 2.0, y1lim, 0),
            justify="bottom-center",
        )
        tit.pickable(False)
        acts.append(tit)

    settings.xtitle = xtitle
    settings.ytitle = ytitle
    asse = Assembly(acts)
    asse.info["yscale"] = yscale
    return asse
Exemple #4
0
def polarPlot(
    rphi,
    title="",
    r1=0,
    r2=1,
    lpos=1,
    lsize=0.03,
    c="blue",
    bc="k",
    alpha=1,
    lw=3,
    deg=False,
    vmax=None,
    fill=True,
    spline=True,
    smooth=0,
    showPoints=True,
    showDisc=True,
    showLines=True,
    showAngles=True,
):
    """
    Polar/radar plot by splining a set of points in polar coordinates.
    Input is a list of polar angles and radii.

    :param str title: histogram title
    :param int bins: number of bins in phi
    :param float r1: inner radius
    :param float r2: outer radius
    :param float lsize: label size
    :param c: color of the line
    :param bc: color of the frame and labels
    :param alpha: alpha of the frame
    :param int lw: line width in pixels
    :param bool deg: input array is in degrees
    :param bool fill: fill convex area with solid color
    :param bool spline: interpolate the set of input points
    :param bool showPoints: show data points
    :param bool showDisc: show the outer ring axis
    :param bool showLines: show lines to the origin
    :param bool showAngles: show angular values

    |polarPlot| |polarPlot.py|_
    """
    if len(rphi) == 2:
        #rphi = list(zip(rphi[0], rphi[1]))
        rphi = np.stack((rphi[0], rphi[1]), axis=1)

    rphi = np.array(rphi)
    thetas = rphi[:, 0]
    radii = rphi[:, 1]

    k = 180 / np.pi
    if deg:
        thetas = np.array(thetas) / k

    vals = []
    for v in thetas:  # normalize range
        t = np.arctan2(np.sin(v), np.cos(v))
        if t < 0:
            t += 2 * np.pi
        vals.append(t)
    thetas = np.array(vals)

    if vmax is None:
        vmax = np.max(radii)

    angles = []
    labs = []
    points = []
    for i in range(len(thetas)):
        t = thetas[i]
        r = (radii[i]) / vmax * r2 + r1
        ct, st = np.cos(t), np.sin(t)
        points.append([r * ct, r * st, 0])
    p0 = points[0]
    points.append(p0)

    r2e = r1 + r2
    if spline:
        lines = shapes.KSpline(points, closed=True)
    else:
        lines = shapes.Line(points)
    lines.c(c).lw(lw).alpha(alpha)

    points.pop()

    ptsact = None
    if showPoints:
        ptsact = shapes.Points(points).c(c).alpha(alpha)

    filling = None
    if fill:
        faces = []
        coords = [[0, 0, 0]] + lines.coordinates().tolist()
        for i in range(1, lines.N()):
            faces.append([0, i, i + 1])
        filling = Actor([coords, faces]).c(c).alpha(alpha)

    back = None
    if showDisc:
        back = shapes.Disc(r1=r2e, r2=r2e * 1.01, c=bc, res=1, resphi=360)
        back.z(-0.01).lighting(diffuse=0, ambient=1).alpha(alpha)

    ti = None
    if title:
        ti = shapes.Text(title, (0, 0, 0),
                         s=lsize * 2,
                         depth=0,
                         justify="top-center")
        ti.pos(0, -r2e * 1.15, 0.01)

    rays = []
    if showDisc:
        rgap = 0.05
        for t in np.linspace(0, 2 * np.pi, num=8, endpoint=False):
            ct, st = np.cos(t), np.sin(t)
            if showLines:
                l = shapes.Line((0, 0, -0.01),
                                (r2e * ct * 1.03, r2e * st * 1.03, -0.01))
                rays.append(l)
            elif showAngles:  # just the ticks
                l = shapes.Line(
                    (r2e * ct * 0.98, r2e * st * 0.98, -0.01),
                    (r2e * ct * 1.03, r2e * st * 1.03, -0.01),
                )
            if showAngles:
                if 0 <= t < np.pi / 2:
                    ju = "bottom-left"
                elif t == np.pi / 2:
                    ju = "bottom-center"
                elif np.pi / 2 < t <= np.pi:
                    ju = "bottom-right"
                elif np.pi < t < np.pi * 3 / 2:
                    ju = "top-right"
                elif t == np.pi * 3 / 2:
                    ju = "top-center"
                else:
                    ju = "top-left"
                a = shapes.Text(int(t * k),
                                pos=(0, 0, 0),
                                s=lsize,
                                depth=0,
                                justify=ju)
                a.pos(r2e * ct * (1 + rgap), r2e * st * (1 + rgap), -0.01)
                angles.append(a)

    mrg = merge(back, angles, rays, labs, ti)
    if mrg:
        mrg.color(bc).alpha(alpha).lighting(diffuse=0, ambient=1)
    rh = Assembly([lines, ptsact, filling] + [mrg])
    rh.base = np.array([0, 0, 0])
    rh.top = np.array([0, 0, 1])
    return rh
Exemple #5
0
def plotxy(
    data,
    xlimits=None,
    ylimits=None,
    xscale=1,
    yscale=None,
    xlogscale=False,
    ylogscale=False,
    c="k",
    alpha=1,
    xtitle="x",
    ytitle="y",
    title="",
    titleSize=None,
    lc="k",
    lw=2,
    dashed=False,
    splined=False,
    marker=None,
    ms=None,
    mc=None,
    ma=None,
):
    """Draw a 2D plot of variable x vs y.

    """

    if len(data) == 2 and len(data[0]) > 1 and len(data[0]) == len(data[1]):
        data = np.c_[data[0], data[1]]

    if xlimits is not None:
        cdata = []
        x0lim = xlimits[0]
        x1lim = xlimits[1]
        for d in data:
            if d[0] > x0lim and d[0] < x1lim:
                cdata.append(d)
        data = cdata
        if not len(data):
            colors.printc("Error in plotxy(): no points within xlimits", c=1)
            return None

    if ylimits is not None:
        cdata = []
        y0lim = ylimits[0]
        y1lim = ylimits[1]
        for d in data:
            if d[1] > y0lim and d[1] < y1lim:
                cdata.append(d)
        data = cdata
        if not len(data):
            colors.printc("Error in plotxy(): no points within ylimits", c=1)
            return None

    data = np.array(data)[:, [0, 1]]

    if xlogscale:
        data[:, 0] = np.log(data[:, 0])

    if ylogscale:
        data[:, 1] = np.log(data[:, 1])

    x0, y0 = np.min(data, axis=0)
    x1, y1 = np.max(data, axis=0)

    if yscale is None:
        yscale = (x1 - x0) / (y1 - y0) * 0.75  # default 3/4 aspect ratio
        yscale = float(utils.precision(yscale, 1))
        if abs(yscale - 1) > 0.2:
            ytitle += " *" + str(yscale)
            y0 *= yscale
            y1 *= yscale
        else:
            yscale = 1

    scale = np.array([[xscale, yscale]])
    data = np.multiply(data, scale)

    acts = []
    if dashed:
        l = shapes.DashedLine(data, lw=lw, spacing=20)
    elif splined:
        l = shapes.KSpline(data).lw(lw).c(lc)
    else:
        l = shapes.Line(data, lw=lw, c=lc)
    acts.append(l)

    if marker:
        if ms is None:
            ms = (x1 - x0) / 75.0
        if mc is None:
            mc = lc
        mk = shapes.Marker(marker, s=ms, alpha=ma)
        pts = shapes.Points(data)
        marked = shapes.Glyph(pts, glyphObj=mk, c=mc)
        acts.append(marked)

    x0lim = x0
    x1lim = x1
    y0lim = y0 * yscale
    y1lim = y1 * yscale
    if xlimits is not None or ylimits is not None:
        if xlimits is not None:
            x0lim = min(xlimits[0], x0)
            x1lim = max(xlimits[1], x1)
        if ylimits is not None:
            y0lim = min(ylimits[0] * yscale, y0)
            y1lim = max(ylimits[1] * yscale, y1)
        rec = shapes.Rectangle([x0lim, y0lim, 0], [x1lim, y1lim, 0])
        rec.alpha(0).wireframe()
        acts.append(rec)

    if title:
        if titleSize is None:
            titleSize = (x1lim - x0lim) / 40.0
        tit = shapes.Text(
            title,
            s=titleSize,
            c=c,
            depth=0,
            alpha=alpha,
            pos=((x1lim + x0lim) / 2.0, y1lim, 0),
            justify="bottom-center",
        )
        tit.pickable(False)
        acts.append(tit)

    settings.xtitle = xtitle
    settings.ytitle = ytitle
    asse = Assembly(acts)
    asse.info["yscale"] = yscale
    return asse