Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e4bfcc0

Browse files
committed
Convert slit paths to compound paths inside cntr.c.
svn path=/trunk/matplotlib/; revision=7422
1 parent 812e132 commit e4bfcc0

2 files changed

Lines changed: 199 additions & 19 deletions

File tree

lib/matplotlib/contour.py

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -539,7 +539,6 @@ def __init__(self, ax, *args, **kwargs):
539539
540540
"""
541541
self.ax = ax
542-
self.noslit = kwargs.get('noslit', False) # **Temporary**
543542
self.levels = kwargs.get('levels', None)
544543
self.filled = kwargs.get('filled', False)
545544
self.linewidths = kwargs.get('linewidths', None)
@@ -599,8 +598,6 @@ def __init__(self, ax, *args, **kwargs):
599598
self.collections = cbook.silent_list('collections.PathCollection')
600599
else:
601600
self.collections = cbook.silent_list('collections.LineCollection')
602-
self.segs = []
603-
self.kinds = []
604601
# label lists must be initialized here
605602
self.labelTexts = []
606603
self.labelCValues = []
@@ -629,8 +626,6 @@ def __init__(self, ax, *args, **kwargs):
629626
alpha=self.alpha)
630627
self.ax.add_collection(col)
631628
self.collections.append(col)
632-
self.segs.append(segs)
633-
self.kinds.append(kinds)
634629
else:
635630
tlinewidths = self._process_linewidths()
636631
self.tlinewidths = tlinewidths
@@ -639,7 +634,7 @@ def __init__(self, ax, *args, **kwargs):
639634
nlist = C.trace(level)
640635
nseg = len(nlist)//2
641636
segs = nlist[:nseg]
642-
kinds = nlist[nseg:]
637+
#kinds = nlist[nseg:]
643638
col = collections.LineCollection(segs,
644639
linewidths = width,
645640
linestyle = lstyle,
@@ -648,24 +643,16 @@ def __init__(self, ax, *args, **kwargs):
648643
col.set_label('_nolegend_')
649644
self.ax.add_collection(col, False)
650645
self.collections.append(col)
651-
self.segs.append(segs)
652-
self.kinds.append(kinds)
653646
self.changed() # set the colors
654647

655648
def _make_paths(self, segs, kinds):
656649
paths = []
657650
for seg, kind in zip(segs, kinds):
658-
codes = np.zeros(kind.shape, dtype=mpath.Path.code_type)
659-
codes.fill(mpath.Path.LINETO)
660-
codes[0] = mpath.Path.MOVETO
661-
# points that begin a slit or are in it:
662-
# use moveto for any point *following* such a point
663-
if self.noslit:
664-
in_slit = kind[:-1] >= _cntr._slitkind
665-
codes[1:][in_slit] = mpath.Path.MOVETO
666-
paths.append(mpath.Path(seg, codes))
651+
paths.append(mpath.Path(seg, codes=kind))
667652
return paths
668653

654+
655+
669656
def changed(self):
670657
tcolors = [ (tuple(rgba),) for rgba in
671658
self.to_rgba(self.cvalues, alpha=self.alpha)]

src/cntr.c

Lines changed: 195 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,12 +1318,204 @@ void cntr_del(Csite *site)
13181318
site = NULL;
13191319
}
13201320

1321+
#define MOVETO 1
1322+
#define LINETO 2
13211323

1322-
/* Build a list of XY 2-D arrays, shape (N,2), to which a list of K arrays
1323-
is concatenated. */
1324+
int reorder(double *xpp, double *ypp, short *kpp,
1325+
double *xy, unsigned char *c, int npts)
1326+
{
1327+
int *i0;
1328+
int *i1;
1329+
int *subp=NULL; /* initialized to suppress warning */
1330+
int isp, nsp;
1331+
int iseg, nsegs;
1332+
int isegplus;
1333+
int i;
1334+
int k;
1335+
int started;
1336+
int maxnsegs = npts/2 + 1;
1337+
1338+
/* allocate maximum possible size--gross overkill */
1339+
i0 = malloc(maxnsegs * sizeof(int));
1340+
i1 = malloc(maxnsegs * sizeof(int));
1341+
1342+
/* Find the segments. */
1343+
iseg = 0;
1344+
started = 0;
1345+
for (i=0; i<npts; i++)
1346+
{
1347+
if (started)
1348+
{
1349+
if ((kpp[i] >= kind_slit_up) || (i == npts-1))
1350+
{
1351+
i1[iseg] = i;
1352+
started = 0;
1353+
iseg++;
1354+
if (iseg == maxnsegs)
1355+
{
1356+
k = -1;
1357+
goto ending;
1358+
}
1359+
}
1360+
}
1361+
else if ((kpp[i] < kind_slit_up) && (i < npts-1))
1362+
{
1363+
i0[iseg] = i;
1364+
started = 1;
1365+
}
1366+
}
1367+
1368+
nsegs = iseg;
1369+
1370+
1371+
/* Find the subpaths as sets of connected segments. */
1372+
1373+
subp = malloc(nsegs * sizeof(int));
1374+
for (i=0; i<nsegs; i++) subp[i] = -1;
1375+
1376+
nsp = 0;
1377+
for (iseg=0; iseg<nsegs; iseg++)
1378+
{
1379+
/* For each segment, if it is not closed, look ahead for
1380+
the next connected segment.
1381+
*/
1382+
double xend, yend;
1383+
xend = xpp[i1[iseg]];
1384+
yend = ypp[i1[iseg]];
1385+
if (subp[iseg] >= 0) continue;
1386+
subp[iseg] = nsp;
1387+
nsp++;
1388+
if (iseg == nsegs-1) continue;
1389+
for (isegplus = iseg+1; isegplus < nsegs; isegplus++)
1390+
{
1391+
if (subp[isegplus] >= 0) continue;
1392+
1393+
if (xend == xpp[i0[isegplus]] && yend == ypp[i0[isegplus]])
1394+
{
1395+
subp[isegplus] = subp[iseg];
1396+
xend = xpp[i1[isegplus]];
1397+
yend = ypp[i1[isegplus]];
1398+
}
1399+
1400+
}
1401+
}
1402+
1403+
/* Generate the verts and codes from the subpaths. */
1404+
k = 0;
1405+
for (isp=0; isp<nsp; isp++)
1406+
{
1407+
int first = 1;
1408+
for (iseg=0; iseg<nsegs; iseg++)
1409+
{
1410+
int istart, iend;
1411+
if (subp[iseg] != isp) continue;
1412+
iend = i1[iseg];
1413+
if (first)
1414+
{
1415+
istart = i0[iseg];
1416+
}
1417+
else
1418+
{
1419+
istart = i0[iseg]+1; /* skip duplicate */
1420+
}
1421+
for (i=istart; i<=iend; i++)
1422+
{
1423+
xy[2*k] = xpp[i];
1424+
xy[2*k+1] = ypp[i];
1425+
if (first) c[k] = MOVETO;
1426+
else c[k] = LINETO;
1427+
first = 0;
1428+
k++;
1429+
if (k > npts) /* should never happen */
1430+
{
1431+
k = -1;
1432+
goto ending;
1433+
}
1434+
}
1435+
}
1436+
}
1437+
1438+
ending:
1439+
free(i0);
1440+
free(i1);
1441+
free(subp);
1442+
1443+
return k;
1444+
}
1445+
1446+
/* Build a list of XY 2-D arrays, shape (N,2), to which a list of path
1447+
code arrays is concatenated.
1448+
*/
13241449
static PyObject *
13251450
build_cntr_list_v2(long *np, double *xp, double *yp, short *kp,
13261451
int nparts, long ntotal)
1452+
{
1453+
PyObject *all_contours;
1454+
PyArrayObject *xyv;
1455+
PyArrayObject *kv;
1456+
npy_intp dims[2];
1457+
npy_intp kdims[1];
1458+
int i;
1459+
long k;
1460+
1461+
PyArray_Dims newshape;
1462+
1463+
all_contours = PyList_New(nparts*2);
1464+
1465+
for (i=0, k=0; i < nparts; k+= np[i], i++)
1466+
{
1467+
double *xpp = xp+k;
1468+
double *ypp = yp+k;
1469+
short *kpp = kp+k;
1470+
int n;
1471+
1472+
1473+
dims[0] = np[i];
1474+
dims[1] = 2;
1475+
kdims[0] = np[i];
1476+
xyv = (PyArrayObject *) PyArray_SimpleNew(2, dims, PyArray_DOUBLE);
1477+
if (xyv == NULL) goto error;
1478+
kv = (PyArrayObject *) PyArray_SimpleNew(1, kdims, PyArray_UBYTE);
1479+
if (kv == NULL) goto error;
1480+
1481+
n = reorder(xpp, ypp, kpp,
1482+
(double *) xyv->data,
1483+
(unsigned char *) kv->data,
1484+
np[i]);
1485+
if (n == -1) goto error;
1486+
newshape.len = 2;
1487+
dims[0] = n;
1488+
newshape.ptr = dims;
1489+
if (PyArray_Resize(xyv, &newshape, 1, NPY_CORDER) == NULL) goto error;
1490+
1491+
newshape.len = 1; /* ptr, dims can stay the same */
1492+
if (PyArray_Resize(kv, &newshape, 1, NPY_CORDER) == NULL) goto error;
1493+
1494+
1495+
if (PyList_SetItem(all_contours, i, (PyObject *)xyv)) goto error;
1496+
if (PyList_SetItem(all_contours, nparts+i,
1497+
(PyObject *)kv)) goto error;
1498+
}
1499+
return all_contours;
1500+
1501+
error:
1502+
Py_XDECREF(xyv);
1503+
Py_XDECREF(kv);
1504+
Py_XDECREF(all_contours);
1505+
return NULL;
1506+
}
1507+
1508+
#if 0 /* preprocess this out when we are not using it. */
1509+
/* Build a list of XY 2-D arrays, shape (N,2), to which a list of K arrays
1510+
is concatenated.
1511+
This is kept in the code in case we need to switch back to it,
1512+
or in case we need it for investigating the infamous internal
1513+
masked region bug.
1514+
*/
1515+
1516+
static PyObject *
1517+
__build_cntr_list_v2(long *np, double *xp, double *yp, short *kp,
1518+
int nparts, long ntotal)
13271519
{
13281520
PyObject *all_contours;
13291521
PyArrayObject *xyv;
@@ -1364,6 +1556,7 @@ build_cntr_list_v2(long *np, double *xp, double *yp, short *kp,
13641556
return NULL;
13651557
}
13661558

1559+
#endif /* preprocessing out the old version for now */
13671560

13681561

13691562
/* cntr_trace is called once per contour level or level pair.

0 commit comments

Comments
 (0)