Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <pre><code>import matplotlib.pyplot as plt import numpy as np data = np.array([1,1,-1,-1,1]) cmap = np.array([(1,0,0), (0,1,0)]) uniqdata, idx = np.unique(data, return_inverse=True) N = len(data) fig, ax = plt.subplots() plt.scatter(np.zeros(N), np.arange(1, N+1), s=100, c=cmap[idx]) plt.grid() plt.show() </code></pre> <p>yields</p> <p><img src="https://i.stack.imgur.com/JntQk.png" alt="enter image description here"></p> <hr> <p><strong>Explanation:</strong></p> <p>If you print out <code>np.unique(data, return_inverse=True)</code>, you'll see it returns a tuple of arrays:</p> <pre><code>In [71]: np.unique(data, return_inverse=True) Out[71]: (array([-1, 1]), array([1, 1, 0, 0, 1])) </code></pre> <p>The first array says the unique values in <code>data</code> is -1 and 1. The second array assigns the value 0 wherever <code>data</code> is -1 and the value 1 wherever <code>data</code> is 1. Essentially, <code>np.unique</code> allows us to transform <code>[1,1,-1,-1,1]</code> to <code>[1, 1, 0, 0, 1]</code>. Now <code>cmap[idx]</code> is an array of RGB values:</p> <pre><code>In [74]: cmap[idx] Out[74]: array([[0, 1, 0], [0, 1, 0], [1, 0, 0], [1, 0, 0], [0, 1, 0]]) </code></pre> <p>This is an application of so-called <a href="http://docs.scipy.org/numpy/docs/numpy-docs/reference/arrays.indexing.rst/#arrays-indexing" rel="nofollow noreferrer">"fancy indexing" on NumPy arrays</a>. <code>cmap[0]</code> is the first row of <code>cmap</code>. <code>cmap[1]</code> is the second row of <code>cmap</code>. <code>cmap[idx]</code> is an array such that the ith element in <code>cmap[idx]</code> is <code>cmap[idx[i]]</code>. So, you end up with <code>cmap[idx]</code> being a 2D-array where the ith row is <code>cmap[idx[i]]</code>. Thus <code>cmap[idx]</code> can be thought of as a sequence of RGB color values.</p> <hr> <p>If you have more than one set of dots and you wish to plot them in columns, the simplest way I can think of is to call <code>ax.scatter</code> once for each list of <code>data</code>:</p> <pre><code>import matplotlib.pyplot as plt import numpy as np def plot_data(ax, data, xval): N = len(data) uniqdata, idx = np.unique(data, return_inverse=True) ax.scatter(np.ones(N)*xval, np.arange(1, N+1), s=100, c=cmap[idx]) cmap = np.array([(1,0,0), (0,1,0)]) fig, ax = plt.subplots() data = np.array([1,1,-1,-1,1]) data2 = np.array([1,-1,1,1,-1]) plot_data(ax, data, 0) plot_data(ax, data2, 1) plt.grid() plt.show() </code></pre> <p><img src="https://i.stack.imgur.com/OdKZx.png" alt="enter image description here"></p> <p>The nice thing about this is that it is relatively easy to understand. The bad thing about this is that it calls <code>ax.scatter</code> more than once. If you have lots of data sets it is more efficient to collate your data and <em>call <code>ax.scatter</code> once</em>. This is faster for Matplotlib, but its a little more complicated to code:</p> <pre><code>import matplotlib.pyplot as plt import numpy as np import itertools as IT def plot_dots(ax, datasets): N = sum(len(data) for data in datasets) x = np.fromiter( (i for i, data in enumerate(datasets) for j in np.arange(len(data))), dtype='float', count=N) y = np.fromiter( (j for data in datasets for j in np.arange(1, len(data)+1)), dtype='float', count=N) c = np.fromiter( (val for data in datasets for rgb in cmap[np.unique(data, return_inverse=True)[-1]] for val in rgb), dtype='float', count=3*N).reshape(-1,3) ax.scatter(x, y, s=100, c=c) cmap = np.array([(1,0,0), (0,1,0)]) fig, ax = plt.subplots() N = 100 datasets = [np.random.randint(2, size=5) for i in range(N)] plot_dots(ax, datasets) plt.grid() plt.show() </code></pre> <p><img src="https://i.stack.imgur.com/vl6To.png" alt="enter image description here"></p> <hr> <p>References:</p> <ul> <li><a href="http://docs.scipy.org/numpy/docs/numpy-docs/reference/arrays.indexing.rst/#arrays-indexing" rel="nofollow noreferrer">fancy indexing (for NumPy arrays)</a></li> <li><a href="http://docs.scipy.org/doc/numpy/reference/generated/numpy.unique.html" rel="nofollow noreferrer">numpy.unique</a></li> <li><a href="http://matplotlib.org/api/pyplot_api.html#matplotlib.pyplot.scatter" rel="nofollow noreferrer">ax.scatter</a></li> <li><a href="http://docs.scipy.org/doc/numpy/reference/generated/numpy.fromiter.html" rel="nofollow noreferrer">numpy.fromiter</a></li> <li><a href="http://docs.python.org/reference/expressions.html#generator-expressions" rel="nofollow noreferrer">generator expressions</a></li> </ul>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload