4

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!

2 Answers 2

7

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-')
Sign up to request clarification or add additional context in comments.

1 Comment

Seems like the answer to every question I've ever asked on here is Pandas. I should probably up my proficiency in it a bit more. Thanks for the help!
4

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)

1 Comment

Hey, your marker zip is a great idea! Thanks for that!! Almost done with the function, will definitely be adding that.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.