Reputation: 239
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
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:
Upvotes: 2
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:
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
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