/// <summary>
    /// Make a random spread of points and edges, as children of this object.
    /// </summary>
    void MakePlot()
    {
        ScaleNegator scaler     = GetComponent <ScaleNegator>();
        int          totalEdges = 0;

        foreach (var symbolIndexPair in Dataset.indexMap)
        {
            string  symbol = symbolIndexPair.Key;
            int     index  = symbolIndexPair.Value;
            Vector3 p1     = Vector3.Scale(Dataset.points[index], plotScaler);

            GameObject obj = Instantiate(pointPrefab, transform);
            obj.transform.localPosition = p1;

            obj.GetComponent <PlotPoint>().SetupPoint(headTransform, symbol);
            obj.GetComponent <SpriteRenderer>().color = sectorColors.ColorOfCategory(Dataset.categoryMap[symbol]);

            scaler.objectsToScale.Add(obj.transform);
            symbolToObj.Add(symbol, obj);

            //add relevant edges to plot
            foreach (var symbolIndexPair2 in Dataset.indexMap)
            {
                string symbol2 = symbolIndexPair2.Key;
                int    index2  = symbolIndexPair2.Value;
                if (index2 <= index)
                {
                    continue;               //skip adding duplicate edges
                }
                float relation = Dataset.GetRelation(symbol, symbol2);

                if (!float.IsNaN(relation) && Mathf.Abs(relation) > minCorrelation && Mathf.Abs(relation) < maxCorrelation)
                {
                    //instantiate and position edges
                    Vector3    p2      = Vector3.Scale(Dataset.points[index2], plotScaler);
                    Vector3    vec     = (p2 - p1);
                    GameObject edgeObj = Instantiate(edgePrefab, transform);
                    edgeObj.transform.localPosition = (p1 + p2) / 2.0f;
                    edgeObj.transform.localRotation = Quaternion.LookRotation(vec, Vector3.up);
                    edgeObj.transform.localScale    = new Vector3(1, 1, vec.magnitude);

                    edgeObj.GetComponent <PlotEdge>().SetupEdge(symbol, symbol2, relation);

                    AddToIncidence(symbol, edgeObj);
                    AddToIncidence(symbol2, edgeObj);

                    edgeObj.SetActive(false);

                    totalEdges += 1;
                }
            }
        }
        Debug.Log(totalEdges + " total edges");
    }
    /// <summary>
    /// Make a random spread of points and edges, as children of this object.s
    /// </summary>
    void MakePlot()
    {
        Vector3[] points = new Vector3[pointCount];
        for (int i = 0; i < pointCount; i++) //make 'pointCount'x random points in [-0.5,0.5]^3
        {
            points[i] = new Vector3(
                Random.Range(-.5f, .5f),
                Random.Range(-.5f, .5f),
                Random.Range(-.5f, .5f));
        }

        List <(int, int)> edges = new List <(int, int)>();

        for (int i = 0; i < pointCount; i++)
        {
            for (int j = i + 1; j < pointCount; j++)                   //for each (symmetric!) point pair,
            {
                if ((points[i] - points[j]).magnitude < edgeThreshold) //if points are close enough, add edge
                {
                    edges.Add((i, j));
                }
            }
        }
        Debug.Log(edges.Count + " edges");

        string[] names = tickers.text.Split('\n');

        ScaleNegator scaler = GetComponent <ScaleNegator>();

        for (int i = 0; i < pointCount; i++)
        {
            //make and position points
            GameObject obj = Instantiate(pointPrefab, transform);
            obj.transform.localPosition = Vector3.Scale(points[i], pointRange);

            obj.GetComponent <PlotPoint>().SetupPoint(headTransform, names[i % names.Length]);

            //give random sector and company name
            obj.GetComponent <SpriteRenderer>().color = sectorColors.colors[
                Mathf.FloorToInt(Random.Range(0, sectorColors.colors.Length))];

            scaler.objectsToScale.Add(obj.transform);
        }


        foreach ((int, int)edge in edges)
        {
            //make and position edges
            LineRenderer line = Instantiate(edgePrefab, transform).GetComponent <LineRenderer>();
            line.SetPositions(new Vector3[] { Vector3.Scale(points[edge.Item1], pointRange),
                                              Vector3.Scale(points[edge.Item2], pointRange) });

            if (Random.value > 0.5f) //colour green or red
            //linear interpolation between weak and strong correlation colours
            {
                line.startColor = line.endColor = Color.Lerp(weakPositiveColor, strongPositiveColor, Random.value);
            }
            else
            {
                line.startColor = line.endColor = Color.Lerp(weakNegativeColor, strongNegativeColor, Random.value);
            }
        }
    }