user136819
user136819

Reputation: 239

How to make a scatter plot using dictionary?

I have the following dictionary of keys and values as lists:

comp = {
        0: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
        1: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 
        2: [0.2073837448663338, 0.19919737000568305, 0.24386659105843467, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0], 
        3: [0.2752555116304319, 0.19919737000568305, 0.21704752129294347, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0], 
        4: [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0], 
        5: [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0], 
        6: [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2691379068024452, 0.0, 0.0], 
        7: [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2691379068024452, 0.0, 0.0]
       }

There are 8 values in each list respectively (1 for each node/person for example). The keys can be called 'time-stamps'. And the values are recorded for 8 nodes/persons from time-stamps 0 to 7.

I want to realise a scatter-plot with x-axis being the time-stamps and y-axis being the values, and points on the plot should be the nodes/persons corresponding to their x and y.

The plot should form a cluster of 8 points (nodes) on each time-stamp. I have the following code that partly works, but I think it takes the average of all the 8 values in each list and plots the points as one in the time-stamps:

import pylab
import matplotlib.pyplot as plt

for key in comp:
    #print(key)
    for idx, item in enumerate(comp[key]):

        x = idx
        y = item
        if idx == 0:
            pylab.scatter(x, y, label=key)
        else:
            pylab.scatter(x, y)

pylab.legend()
pylab.show()

Not sure how to create the cluster that I want. Any help is appreciated.

(Using Ubuntu 14.04 32-Bit VM and Python 2.7)

Upvotes: 0

Views: 8247

Answers (3)

asongtoruin
asongtoruin

Reputation: 10359

A slight alternative here, if you're able to use a few other modules. A standard scatter plot is useful, however your data features a large number of overlapping points, which aren't visible in the final graph. For this, seaborn's swarmplot might be useful.

To make life a little easier, I use pandas to reshape the data into a DataFrame and then call the sramplot directly:

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

comp = {
        '0': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        '1': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        '2': [0.2073837448663338, 0.19919737000568305, 0.24386659105843467, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        '3': [0.2752555116304319, 0.19919737000568305, 0.21704752129294347, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        '4': [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        '5': [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        '6': [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2691379068024452, 0.0, 0.0],
        '7': [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2691379068024452, 0.0, 0.0],
        }

df = pd.DataFrame.from_dict(comp, orient='index')
df.index.rename('Observation', inplace=True)

stacked = df.stack().reset_index()
stacked.rename(columns={'level_1': 'Person', 0: 'Value'}, inplace=True)

sns.swarmplot(data=stacked, x='Observation', y='Value', hue='Person')
plt.show()

This gives the following plot:

enter image description here

Upvotes: 2

DavidG
DavidG

Reputation: 25362

I think you are slightly overcomplicating it. If you loop through and get the keys of the dictionary, you can get the values by simply comp[key_name]. This can then be passed to plt.scatter(). You will have to repeat the key 8 times using [key] * 8, in order to pass the whole list of values to scatter:

import matplotlib.pyplot as plt

comp = {
        0: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        1: [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        2: [0.2073837448663338, 0.19919737000568305, 0.24386659105843467, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        3: [0.2752555116304319, 0.19919737000568305, 0.21704752129294347, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        4: [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        5: [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        6: [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2691379068024452, 0.0, 0.0],
        7: [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2691379068024452, 0.0, 0.0]
       }

for key in comp:

    plt.scatter([key]*8, comp[key], label=key)

plt.legend()
plt.show()

Update: To get the colors as you want you can do the following, which is a modified version of the answer given by @lkriener

array = np.zeros((8,8))
for key in comp:
    array[:,key] = comp[key]

x = range(8)
for i in range (8):
    plt.scatter(x, array[i,:], label=i)

plt.legend()
plt.show()

Which gives the figure:

enter image description here

You can move the legend by giving the call to plt.legend() certain arguments. The most important ones are loc and bbox_to_anchor, the documentation of which can be found here

Upvotes: 2

lkriener
lkriener

Reputation: 187

To plot the values of the same node in the same color you could do something like this:

import numpy as np
import matplotlib.pyplot as plt

comp = {
        '0': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        '1': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0],
        '2': [0.2073837448663338, 0.19919737000568305, .24386659105843467,0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        '3': [0.2752555116304319, 0.19919737000568305, 0.21704752129294347, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        '4': [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        '5': [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2703400161511446, 0.0, 0.0],
        '6': [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2691379068024452, 0.0, 0.0],
        '7': [0.2752555116304319, 0.19919737000568305, 0.21782751590851177, 0.25659375810265855, 0.0, 0.2691379068024452, 0.0, 0.0],
        }
array = np.zeros([8,8])
for i, key in enumerate(comp.keys()):
    for j in range(8):
        array[j, i] = comp[key][j]

plt.xlim((-1,8))
plt.ylim((-0.05,0.3))
plt.xlabel('timestamps')
plt.ylabel('values of nodes')
for i in range(8):
    plt.plot(range(8), array[i], ls='--', marker='o', label='node {}'.format(i))
plt.legend(loc='upper_left')
plt.savefig('temp.png')
plt.show()

This would give you the following picture: enter image description here

Upvotes: 1

Related Questions