BigBoy1337
BigBoy1337

Reputation: 5023

Matplotlib: two plots on the same axes with different left right scales

I am trying to use this example: http://matplotlib.org/examples/api/two_scales.html#api-two-scales with my own dataset as shown below:

import sys
import numpy as np
import matplotlib.pyplot as plt
print sys.argv
logfile = sys.argv[1]
data = []
other_data =[]
with open(logfile,'rb') as f:
    for line in f:
        a = line.split(',')
        print a
        data.append(a[1])
        other_data.append(a[2][:-1])
print other_data
x = np.arange(0,len(data))
fig,ax1 = plt.subplots()
ax1.plot(x,np.arange(data))

ax2 = ax1.twinx()
ax2.plot(x,np.arange(other_data))
plt.show()

However, I keep getting this error:

'Traceback (most recent call last):
  File "share/chart.py", line 17, in <module>
    ax1.plot(x,np.arange(data))
TypeError: unsupported operand type(s) for -: 'list' and 'int'

I think I am using the twinx command correctly but apparently not. How can I do this?

Upvotes: 2

Views: 1841

Answers (1)

uhoh
uhoh

Reputation: 3745

try

x1.plot(x,np.array(data))  # do you mean "array" here?

in both places, instead of

x1.plot(x,np.arange(data))

But why do you want to use anything here at all? If you just

x1.plot(data) 

it will generate your x values automatically, and matplotlib will handle a variety of different iterables without converting them.

You should supply an example that someone else can run right away by adding some sample data. That may help you debug also. It's called a Minimal, Complete, and Verifiable Example.

You can get rid of some of that script too:

import matplotlib.pyplot as plt

things = ['2,3', '4,7', '4,1', '5,5']

da, oda = [], []
for thing in things:
    a, b = thing.split(',')
    da.append(a)
    oda.append(b)

fig, ax1 = plt.subplots()
ax2      = ax1.twinx()

ax1.plot(da)
ax2.plot(oda)

plt.savefig("da oda")  # save to a .png so you can paste somewhere
plt.show()

note 1: matplotlib is generating the values for the x axis for you as default. You can put them in if you want, but that's just an opportunity to make a mistake.

note 2: matplotlib is accepting the strings and will try to convert to numerical values for you.

if you want to embrace python, use a list comprehension and then zip(*) - which is the inverse of zip():

import matplotlib.pyplot as plt

things = ['2,3', '4,7', '4,1', '5,5']

da, oda = zip(*[thing.split(',') for thing in things])

fig, ax1 = plt.subplots()
ax2      = ax1.twinx()

ax1.plot(da)
ax2.plot(oda)

plt.savefig("da oda")  # save to a .png so you can paste somewhere
plt.show()

But if you really really want to use arrays, then transpose - array.T - does what zip(*) does will also work for nested iterables. However you should convert to numerical values first using int() or float():

import matplotlib.pyplot as plt
import numpy as np

things = ['2,3', '4,7', '4,1', '5,5']

strtup = [thing.split(',') for thing in things]
inttup = [(int(a), int(b)) for a, b  in strtup]

da, oda = np.array(inttup).T

fig, ax1 = plt.subplots()
ax2      = ax1.twinx()

ax1.plot(da)
ax2.plot(oda)

plt.savefig("da oda")
plt.show()

enter image description here

Upvotes: 3

Related Questions