简体   繁体   中英

Python3 TypeError: 'value' must be an instance of str or bytes, not a tuple

I am new to python and trying to investigate the stock market with it. I've got a double indexed dataframe of stock data from a few companies and I'm trying to plot it on a graph where each line is a company. I was getting the error in the title on the plt.plot() line, and when I tried to just select stock from one company and I got the same error

# import libraries
import pandas_datareader as pdr
import datetime
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('fivethirtyeight')

# load the data
def get(tickers, startdate, enddate):
    def data(ticker):
        return (pdr.get_data_yahoo(ticker, start=startdate, end=enddate))
    datas = map (data, tickers)
    return(pd.concat(datas, keys=tickers, names=['Ticker', 'Date']))

tickers = ['AAPL', 'MSFT', 'IBM', 'GOOG']
all_data = get(tickers, datetime.datetime(2018, 1, 1), datetime.datetime(2020, 10, 1))

# AAPL only
aapl = all_data[all_data.index.get_loc('AAPL')]

# visualize the stock price
plt.figure(figsize=(12.2, 4.5))
plt.plot(aapl['Close'], label='Close')
plt.title('Close Price History')
plt.xlabel('Date')
plt.ylabel('Price USD ($)')
plt.show()

EDIT: here is the full traceback as requested in comments

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-11-506d7434af31> in <module>
      1 # visualize the stock price
      2 plt.figure(figsize=(12.2, 4.5))
----> 3 plt.plot(all_data['Close'], label='Close')
      4 plt.title('Close Price History')
      5 plt.xlabel('Date')

/opt/miniconda3/envs/ds383/lib/python3.8/site-packages/matplotlib/pyplot.py in plot(scalex, scaley, data, *args, **kwargs)
   2822 @_copy_docstring_and_deprecators(Axes.plot)
   2823 def plot(*args, scalex=True, scaley=True, data=None, **kwargs):
-> 2824     return gca().plot(
   2825         *args, scalex=scalex, scaley=scaley,
   2826         **({"data": data} if data is not None else {}), **kwargs)

/opt/miniconda3/envs/ds383/lib/python3.8/site-packages/matplotlib/axes/_axes.py in plot(self, scalex, scaley, data, *args, **kwargs)
   1741         """
   1742         kwargs = cbook.normalize_kwargs(kwargs, mlines.Line2D)
-> 1743         lines = [*self._get_lines(*args, data=data, **kwargs)]
   1744         for line in lines:
   1745             self.add_line(line)

/opt/miniconda3/envs/ds383/lib/python3.8/site-packages/matplotlib/axes/_base.py in __call__(self, data, *args, **kwargs)
    271                 this += args[0],
    272                 args = args[1:]
--> 273             yield from self._plot_args(this, kwargs)
    274 
    275     def get_next_color(self):

/opt/miniconda3/envs/ds383/lib/python3.8/site-packages/matplotlib/axes/_base.py in _plot_args(self, tup, kwargs)
    392 
    393         if self.axes.xaxis is not None:
--> 394             self.axes.xaxis.update_units(x)
    395         if self.axes.yaxis is not None:
    396             self.axes.yaxis.update_units(y)

/opt/miniconda3/envs/ds383/lib/python3.8/site-packages/matplotlib/axis.py in update_units(self, data)
   1461         neednew = self.converter != converter
   1462         self.converter = converter
-> 1463         default = self.converter.default_units(data, self)
   1464         if default is not None and self.units is None:
   1465             self.set_units(default)

/opt/miniconda3/envs/ds383/lib/python3.8/site-packages/matplotlib/category.py in default_units(data, axis)
    105         # the conversion call stack is default_units -> axis_info -> convert
    106         if axis.units is None:
--> 107             axis.set_units(UnitData(data))
    108         else:
    109             axis.units.update(data)

/opt/miniconda3/envs/ds383/lib/python3.8/site-packages/matplotlib/category.py in __init__(self, data)
    174         self._counter = itertools.count()
    175         if data is not None:
--> 176             self.update(data)
    177 
    178     @staticmethod

/opt/miniconda3/envs/ds383/lib/python3.8/site-packages/matplotlib/category.py in update(self, data)
    209         for val in OrderedDict.fromkeys(data):
    210             # OrderedDict just iterates over unique values in data.
--> 211             cbook._check_isinstance((str, bytes), value=val)
    212             if convertible:
    213                 # this will only be called so long as convertible is True.

/opt/miniconda3/envs/ds383/lib/python3.8/site-packages/matplotlib/cbook/__init__.py in _check_isinstance(_types, **kwargs)
   2233     for k, v in kwargs.items():
   2234         if not isinstance(v, types):
-> 2235             raise TypeError(
   2236                 "{!r} must be an instance of {}, not a {}".format(
   2237                     k,

TypeError: 'value' must be an instance of str or bytes, not a tuple

As mentioned in the comments it is important to first understand the traceback:

  File "type_error.py", line 25, in <module>
    plt.plot(aapl['Close'], label='Close')
  File "/home/phihei00/.virtualenvs/stackoverlow/lib/python3.6/site-packages/matplotlib/pyplot.py", line 2842, in plot
    **({"data": data} if data is not None else {}), **kwargs)
  File "/home/phihei00/.virtualenvs/stackoverlow/lib/python3.6/site-packages/matplotlib/axes/_axes.py", line 1743, in plot
    lines = [*self._get_lines(*args, data=data, **kwargs)]
  File "/home/phihei00/.virtualenvs/stackoverlow/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 273, in __call__
    yield from self._plot_args(this, kwargs)
  File "/home/phihei00/.virtualenvs/stackoverlow/lib/python3.6/site-packages/matplotlib/axes/_base.py", line 394, in _plot_args
    self.axes.xaxis.update_units(x)
  File "/home/phihei00/.virtualenvs/stackoverlow/lib/python3.6/site-packages/matplotlib/axis.py", line 1463, in update_units
    default = self.converter.default_units(data, self)
  File "/home/phihei00/.virtualenvs/stackoverlow/lib/python3.6/site-packages/matplotlib/category.py", line 107, in default_units
    axis.set_units(UnitData(data))
  File "/home/phihei00/.virtualenvs/stackoverlow/lib/python3.6/site-packages/matplotlib/category.py", line 176, in __init__
    self.update(data)
  File "/home/phihei00/.virtualenvs/stackoverlow/lib/python3.6/site-packages/matplotlib/category.py", line 211, in update
    cbook._check_isinstance((str, bytes), value=val)
  File "/home/phihei00/.virtualenvs/stackoverlow/lib/python3.6/site-packages/matplotlib/cbook/__init__.py", line 2251, in _check_isinstance
    type_name(type(v))))
TypeError: 'value' must be an instance of str or bytes, not a tuple

It seems you are passing something to plt.plot() as first argument that is wrong.

Let's use a debugger ( breakpoint() if python >= 3.7 else import ipdb; ipdb.set_trace() or your favorite editor) to inspect this:

ipdb> type(aapl["Close"])
<class 'pandas.core.series.Series'>

This will show you the type of your data. This combined with a short google search will lead you to the pandas documentationhttps://pandas.pydata.org/docs/reference/api/pandas.Series.html where you will find that this class has a method to_numpy

So we insert the patch:

plt.plot(aapl['Close'].to_numpy(), label='Close')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM