I am a student working with python dictionaries for the first time and I'm getting stuck on resorting them in to matrix arrays.
I have a nested ordered dictionary describing the temperature and humidity week by week.
weather = OrderedDict([(92, OrderedDict([('Mon', 79), ('Tues', 85),
('Weds', 87), ('Thurs', 83)])),
(96, OrderedDict([('Mon', 65), ('Tues', 71),
('Weds', 74), ('Thurs', 68)])),
(91, OrderedDict([('Mon', 83), ('Tues', 84),
('Weds', 82), ('Thurs', 80)]))])
The overall key for each week indicates average humidity, and the individual values for each day are temperature.
I am trying to create a single figure plot in matplotlib of lines of temperature vs. day that will use humidity as a third variable to indicate the color from a colorbar. It seems that LineCollection will do this with a 2D array of day and temperature. But when I try to pull out the 2D array from the nested dictionary, I cannot seem to get it into the necessary Nx2 shape for LineCollection.
Any help is greatly appreciated!
Here's the code I have so far:
plt.figure()
x=[]
y=[]
z=[]
ticks=[]
for humidity, data_dict in weather.iteritems():
x.append(range(len(data_dict)))
y.append(data_dict.values())
z.append(humidity)
ticks.append(data_dict.keys())
for ii in x,y,z:
ii = np.array(ii)
lines=np.array(zip(x,y))
print lines.shape
And this returns that the shape is (3, 2, 4) instead of (3, 2)
EDIT: I'm hoping for lines in an output that looks like this, so numpy can recognize it as a 3x2 2D-array:
[[(0 1 2 3), (79 85 87 83)],
[(0 1 2 3), (65 71 74 68)],
[(0 1 2 3), (83 84 82 80)]]
You need to loop through the nested dictionaries appending values to a list. You also should store the day number so as to have something to plot temperature against. The colour for humidity should also be stored for each day. You then need to define the axis label to display the days as strings. The code to do this looks like,
from collections import OrderedDict
import matplotlib.pyplot as plt
weather = OrderedDict([(92, OrderedDict([('Mon', 79),
('Tues', 85),
('Weds', 87),
('Thurs', 83)])),
(96, OrderedDict([('Mon', 65),
('Tues', 71),
('Weds', 74),
('Thurs', 68)])),
(91, OrderedDict([('Mon', 83),
('Tues', 84),
('Weds', 82),
('Thurs', 80)]))])
Temp = []
Humidity = []
Day = []
Dayno = []
for h, v in weather.items():
j = 0
for d, T in v.items():
Temp.append([T])
Humidity.append([h])
Day.append([d])
Dayno.append([j])
j += 1
fig,ax = plt.subplots(1,1)
cm = ax.scatter(Dayno, Temp, c=Humidity,
vmin=90., vmax=100.,
cmap=plt.cm.RdYlBu_r)
ax.set_xticks(Dayno[0:4])
ax.set_xticklabels(Day[0:4])
plt.colorbar(cm)
plt.show()
which plots,

UPDATE: If you want to use plots, you need to separate the data into an array for each week and then plot these as single line. You can then set the colour for each line and label. I've attached a version using numpy and array slicing (although probably not simplest solution),
from collections import OrderedDict
import matplotlib.pyplot as plt
import matplotlib
import numpy as np
weather = OrderedDict([(92, OrderedDict([('Mon', 79),
('Tues', 85),
('Weds', 87),
('Thurs', 83)])),
(96, OrderedDict([('Mon', 65),
('Tues', 71),
('Weds', 74),
('Thurs', 68)])),
(91, OrderedDict([('Mon', 83),
('Tues', 84),
('Weds', 82),
('Thurs', 80)]))])
Temp = []; Humidity = []
Day = []; Dayno = []; weekno = []
i = 0
for h, v in weather.items():
j = 0
for d, T in v.items():
Temp.append(T)
Humidity.append(h)
Day.append(d)
Dayno.append(j)
weekno.append(i)
j += 1
i += 1
#Swtich to numpy arrays to allow array slicing
Temp = np.array(Temp)
Humidity = np.array(Humidity)
Day = np.array(Day)
Dayno = np.array(Dayno)
weekno = np.array(weekno)
#Plot lines
fig,ax = plt.subplots(1,1)
vmin=90.; vmax=97.;
weeks=3; daysperweek=4
colour = ['r', 'g', 'b']
for i in range(weeks):
ax.plot(Dayno[weekno==i],
Temp[weekno==i],
c=colour[i],
label="Humidity = " + str(Humidity[daysperweek*i]))
ax.set_xticks(Dayno[0:4])
ax.set_xticklabels(Day[0:4])
plt.legend(loc="best")
plt.show()
Which looks like,

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With