Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plot data stored in list of dicts using list comprehension

I have a netCDF file containing monthly average temperatures around the globe dating back to 1948. For an assignment, I have to select any one provided datapoint, extract its mean temperature values for the months of December, January, February, and March, and then display it.

I've already unpacked the data and I have it collected in a list of dictionaries, as shown here:

For December:

decemberMeans = [
    {'year': 1948, 'temp': 271.24}, {'year': 1949, 'temp': 271.28},
    {'year': 1950, 'temp': 268.52}, {'year': 1951, 'temp': 269.63},
    ...,
    {'year': 2015, 'temp': 277.23}, {'year': 2016, 'temp': 271.25}
]

Data corresponding to January, February, and March is structured in the same manner.

My next step is to plot it. I have to plot one line on the same graph for each set of data, and I'm using list comprehensions to do it. Right now my plotting code looks like this:

import matplotlib.pyplot as plt

plt.figure(1)
plt.hold(True)
plt.plot([data['years'] for data in decemberMeans], \
    [data['temp'] for data in decemberMeans], 'k-')
plt.plot([data['years'] for data in januaryMeans], \
    [data['temp'] for data in januaryMeans], 'r-')
plt.plot([data['years'] for data in februaryMeans], \
    [data['temp'] for data in februaryMeans], 'b-')
plt.plot([data['years'] for data in marchMeans], \
    [data['temp'] for data in marchMeans], 'y-')
plt.grid(True)
plt.show()
plt.close()

It plots just fine, but I can see that all of my list comprehensions are really redundant. Would there be a way that I could unpack the dictionary values in one fowl swoop so that I don't have to write data['...'] for data in list twice for each set?


P.S. - As I'm writing this I've started to realize that I could write a function to do the plotting (which would probably take even less time than writing out this post), but I'm still curious to know. Thanks to all in advance!

like image 433
nat5142 Avatar asked Sep 06 '25 11:09

nat5142


2 Answers

You can use pandas for that:

import matplotlib.pyplot as plt
import pandas as pd

decemberMeans = [
    {'year': 1948, 'temp': 271.24}, {'year': 1949, 'temp': 271.28},
    {'year': 1950, 'temp': 268.52}, {'year': 1951, 'temp': 269.63},
    {'year': 2015, 'temp': 277.23}, {'year': 2016, 'temp': 271.25}
]  
df = pd.DataFrame(decemberMeans)

plt.figure(1)
plt.plot(df['year'], df['temp'], 'k-')
like image 108
Julien Avatar answered Sep 09 '25 00:09

Julien


Yes pandas is definitely the way to go! Have a look at the examples here (second example should be exactly what you want, if you can get your data in that form). More generally though, there are a few things you can do to avoid the kind of repetition you have come across.

Writing a function for commonly used code is a great start. It sounds like you have already come up with something like this:

def myplot(monthMeans, marker):
    plt.plot([data['years'] for data in monthMeans],
             [data['temp'] for data in monthMeans],
             marker)

And then your code to plot each series to the active figure becomes:

myplot(decemberMeans, 'k-')
myplot(januaryMeans, 'r-')
myplot(februaryMeans, 'b-')
myplot(marchMeans, 'y-')

But this is still not ideal - what if you changed the name of myplot and had to change every line? You can shorten things again, because Python lets you create lists of anything:

allMonthMeans = [decemberMeans, januaryMeans, ...]
markers = ['k-', 'r-', ...]

# 'zip' loops over the two lists simultaneously
for monthMeans, marker in zip(allMonthMeans, markers):
    myplot(monthMeans, marker)
like image 22
Simon Bowly Avatar answered Sep 09 '25 01:09

Simon Bowly