Crash in T-SNE

### Describe the bug

I got a crash using the (external) [hdbscan package](https://github.com/scikit-learn-contrib/hdbscan) in some special situation. I [debugged it](https://github.com/scikit-learn-contrib/hdbscan/issues/623) and found out that it happens in the scikit-learn package, specifically its T-SNE implementation. The hdbscan maintainer ([Leland McInnes](https://github.com/lmcinnes)!) suggested to report it here.

Is this something that should be guarded for in scikit-learn?

### Steps/Code to Reproduce

The simplest way to reproduce it (using the hdbscan package) is:
```py
import numpy as np
import hdbscan
model = hdbscan.HDBSCAN(gen_min_span_tree=True)
data = np.zeros((91, 3))
clustering = model.fit(data)
clustering.minimum_spanning_tree_.plot()
```
Note that it also happens when only a relative small proportion of points are equal (but only sometimes?), this is just the easiest way to show it. By default some warnings are displayed:
> ...\sklearn\decomposition\_pca.py:685: RuntimeWarning: invalid value encountered in divide
>   self.explained_variance_ratio_ = self.explained_variance_ / total_var
> ...\sklearn\manifold\_t_sne.py:1002: RuntimeWarning: invalid value encountered in divide
>   X_embedded = X_embedded / np.std(X_embedded[:, 0]) * 1e-4 

In the end it appears to be a problem in `sklearn.manifold._t_sne._barnes_hut_tsne.gradient()`, not (always?) being able to handle `nan` values. For example, this reproduces the crash:
```py
import numpy as np
from sklearn.manifold._t_sne import _barnes_hut_tsne
neighbors = np.array([1, 2, 0, 2, 0, 1], dtype='int64')
val_P = np.full_like(neighbors, 2 / 45, dtype='float32')
pos_output = np.full((3, 2), np.nan, dtype='float32')
forces = np.zeros_like(pos_output)
indptr = np.arange(7, step=2, dtype='int64')
_barnes_hut_tsne.gradient(val_P, pos_output, neighbors, indptr, forces, 0.5, 2, 11)
```
One layer deeper, the crash occurs inside `sklearn.neighbors._quad_tree._QuadTree.build_tree()`, as follows:
```py
import numpy as np
from sklearn.neighbors._quad_tree import _QuadTree
qt = _QuadTree(2, 11)
X = np.full((3, 2), np.nan, dtype='float32')
qt.build_tree(X)
```
The output of this (due to `verbose=11`) up to the crash is:
> [QuadTree] bounding box axis 0 : [nan, nan]
> [QuadTree] bounding box axis 1 : [nan, nan]
> [QuadTree] Inserting depth 0
> [QuadTree] inserted point 0 in cell 0
> [QuadTree] Inserting depth 0
> [QuadTree] inserted point 0 in new child 1
> [QuadTree] Inserting depth 0
> [QuadTree] Inserting depth 1
> ...
> [QuadTree] Inserting depth 6271
> [QuadTree] inserted point 0 in new child 6272
> [QuadTree] Inserting depth 6271
> [QuadTree] Inserting depth 6272

I didn't dig into the QuadTree code.

### Expected Results

I would expect anything but Python crashing.

### Actual Results

Python crashed: its console window just went away silently (on Windows).

### Versions

```shell
System:
    python: 3.12.1 (tags/v3.12.1:2305ca5, Dec  7 2023, 22:03:25) [MSC v.1937 64 bit (AMD64)]
executable: C:\Users\Public\Software\Python\python.exe
   machine: Windows-11-10.0.22631-SP0

Python dependencies:
      sklearn: 1.4.0
          pip: 23.3.2
   setuptools: 69.0.3
        numpy: 1.26.3
        scipy: 1.12.0
       Cython: 3.0.8
       pandas: 2.2.0
   matplotlib: 3.8.2
       joblib: 1.3.2
threadpoolctl: 3.2.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 16
         prefix: libopenblas
       filepath: C:\Users\Public\Software\Python\Lib\site-packages\numpy.libs\libopenblas64__v0.3.23-293-gc2f4bdbb-gcc_10_3_0-2bde3a66a51006b2b53eb373ff767a3f.dll
        version: 0.3.23.dev
threading_layer: pthreads
   architecture: Cooperlake

       user_api: openmp
   internal_api: openmp
    num_threads: 16
         prefix: vcomp
       filepath: C:\Users\Public\Software\Python\Lib\site-packages\sklearn\.libs\vcomp140.dll
        version: None

       user_api: blas
   internal_api: openblas
    num_threads: 16
         prefix: libopenblas
       filepath: C:\Users\Public\Software\Python\Lib\site-packages\scipy.libs\libopenblas_v0.3.20-571-g3dec11c6-gcc_10_3_0-c2315440d6b6cef5037bad648efc8c59.dll
        version: 0.3.21.dev
threading_layer: pthreads
   architecture: Cooperlake
```

COMMENT:
Thanks a lot for the stand-alone code snippets, I can reproduce the error from your first snippet on Linux so at least this is not Windows-specific.

My wild-guess is that nans should be dealt with by higher level code before reaching low-level Cython code that likely is not meant to handle nans.

Here is some additional info from gdb (not that useful I am afraid):
```
Thread 1 "python" received signal SIGSEGV, Segmentation fault.
0x00007fffb3bc5f69 in __pyx_f_7sklearn_9neighbors_10_quad_tree_9_QuadTree_insert_point () from /home/lesteve/micromamba/envs/del2/lib/python3.12/site-packages/sklearn/neighbors/_quad_tree.cpython-312-x86_64-linux-gnu.so
```

My understanding is that the issue comes from some plotting code that is specific to the hdbscan package and does a PCA followed by a TSNE:
https://github.com/scikit-learn-contrib/hdbscan/blob/98928d0c095715edc9584e7989bd8559673bc2f0/hdbscan/plots.py#L824-L832

I am not too sure whether PCA, TSNE or the hdbscan-specific plotting code should be responsible for erroring with a nice error message when there are nans.

Labels: Bug, help wanted, module:manifold, cython