0

Trying to create a simple graph using a list of lists with year and value:

test_file = [[2000, 3.8], [2001, -2.4], [2002, 5.8], [2003, -10.5],
             [2004, 2.1], [2005, 2.1], [2006, 6.9], [2007, -3.9]]

for i in test_file:
    plot(test_file[i][0], test_file[i][1], marker="o",
         color="blue", markeredgecolor="black")
    axis([2000, 2007, -12, 10])
    show()

But I'm getting this error: TypeError: list indices must be integers or slices, not list

Thanks.

3 Answers 3

2

If you don't mind importing numpy, converting the list to an array works pretty painlessly:

import numpy as np
import matplotlib.pyplot as plt

test_file = [[2000, 3.8], [2001, -2.4], [2002, 5.8], [2003, -10.5], [2004, 2.1], [2005, 2.1], [2006, 6.9], [2007, -3.9]]
test_file = np.array(test_file)

plt.plot(test_file[:, 0], test_file[:, 1])
plt.show()
Sign up to request clarification or add additional context in comments.

1 Comment

I will also try this.
0

if you write for i in test_file what happens is that python iterates through the array test_file and in the first iteration takes the first item [2000, 3.8] and assigns i to this. This is not what you want. You should change your code into something like this:

from matplotlib.pyplot import plot, axis, show

test_file = [[2000, 3.8], [2001, -2.4], [2002, 5.8], [2003, -10.5], [2004, 2.1], [2005, 2.1], [2006, 6.9], [2007, -3.9]]
for year, value in test_file:
    plot(year, value, marker="o", color="blue", markeredgecolor="black")

axis([2000, 2007, -12, 10])
show()

there is no line connecting the dots

In this case you need to reform your data a bit:

dates = [i[0] for i in test_file]
values = [i[1] for i in test_file]
plot(dates, values, '-o', color="blue", markeredgecolor="black")

x-axis is 1-7 vs. 2000 - 2007

Yes, this is a little bit odd. One way to fix this is to turn the years which are now stored as integers into python datetime.date and run autofmt_xdate() on them, so the whole code reads:

from matplotlib.pyplot import plot_date, axis, show, gcf
import datetime

test_file = [[2000, 3.8], [2001, -2.4], [2002, 5.8], [2003, -10.5], [2004, 2.1], [2005, 2.1], [2006, 6.9], [2007, -3.9]]

dates = [datetime.date(i[0], 1, 1) for i in test_file]
values = [i[1] for i in test_file]
plot_date(dates, values, "-o", color="blue", markeredgecolor="black")
gcf().autofmt_xdate()
show()

3 Comments

Same issue as below: x-axis is 1-7 vs. 2000 - 2007 and there are no lines connecting the dots.
with the first to lines (dates= and values=) you split them into two arrays. To connect the dots matplotlib needs to have the whole lists and not just single dots as you did before. Why that is I cannot say, this you'd need to ask in the matplotlib community
@user42760 I added some info on how to fix the x axis issue
0

For line connecting dots, you need to specify plot data together in a list as below.

Bonus: I added x , y low and high value as variables instead of hardcoded in case data in test_file changes.

EDIT
Added ScalerFormatter to the code for y-axis to show actual y-axis values.

import matplotlib.pyplot as plt
from  matplotlib import ticker
import math

test_file = [[2000, 3.8], [2001, -2.4], [2002, 5.8], [2003, -10.5], [2004, 2.1], [2005, 2.1], [2006, 6.9], [2007, -3.9]]
year   = [ i[0] for i in test_file]
value  = [ i[1] for i in test_file]
x_low  = min (year)
x_high = max(year)

y_low = float(math.floor(min(value)))
y_high = float(math.ceil(max(value)))

plt.xlabel('Year')
plt.ylabel('Value')
plt.title('Year and Value')


plt.plot(year ,value, marker="o", color="black", markeredgecolor="black")
plt.axis([x_low , x_high, y_low, y_high])

fmt=ticker.ScalarFormatter(useOffset=False)
fmt.set_scientific(False)
ax=plt.gca()
ax.xaxis.set_major_formatter(fmt)

plt.show()

Default Plot

Default Plot

Plot with Actual Y-Axis Data Formatted Plot

4 Comments

Nice, but how do I get the x-axis to show the year (2000-2007) not the number (1-7). And the lines are blue and not black
See edits above. For black color for lines, Simply change color="black" in plt.plot and for plot to show actual y-axis data instead of default sequence. I added Scalerformatter method to set the default to off. Hope this helps.
This is great. Also very helpful to see different approaches to the same issue.
If its helpful, up-voting would be encouraging.

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.