TypeError: unhashable type: ‘Scatter’ when trying to create scatter plot with multiple axes


#1

Hi,

Just trying to build upon the example in the tutorial that creates a scatter plot from a pandas dataframe. Attempted to add a second y-axes using the code below:

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd

app = dash.Dash()

df = pd.read_csv(
    'https://gist.githubusercontent.com/chriddyp/' +
    '5d1ea79569ed194d432e56108a04d188/raw/' +
    'a9f9e8076b837d541398e999dcbac2b2826a81f8/'+
    'gdp-life-exp-2007.csv')


app.layout = html.Div([
    dcc.Graph(
        id='life-exp-vs-gdp',
        figure={
            'data': [
                {
                go.Scatter(
                    x=df[df['continent'] == i]['gdp per capita'],
                    y=df[df['continent'] == i]['life expectancy'],
                    text=df[df['continent'] == i]['country'],
                    mode='markers',
                    opacity=0.7,
                    marker={
                        'size': 15,
                        'line': {'width': 0.5, 'color': 'white'}
                    },
                    name=i
                ) for i in df.continent.unique()
                },
                {
                go.Scatter(
                    x=df[df['continent'] == i]['gdp per capita'],
                    y=df[df['continent'] == i]['population'],
                    text=df[df['continent'] == i]['country'],
                    mode='markers',
                    opacity=0.7,
                    marker={
                        'size': 15,
                        'line': {'width': 0.5, 'color': 'white'}
                    },
                    name=i
                ) for i in df.continent.unique()
                }
            ],
            'layout': go.Layout(
                xaxis={'type': 'log', 'title': 'GDP Per Capita'},
                yaxis={'title': 'Life Expectancy'},
                margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
                legend={'x': 0, 'y': 1},
                hovermode='closest'
            )
        }
    )
])

if __name__ == '__main__':
    app.run_server()

However when I try to run app.py I get the error:

Traceback (most recent call last):
  File "graph_from_dataframe.py", line 33, in <module>
    ) for i in df.continent.unique()
  File "graph_from_dataframe.py", line 33, in <setcomp>
    ) for i in df.continent.unique()
TypeError: unhashable type: 'Scatter'

I’ve seen examples with multiple axes where a html file is generated but I’m trying to do something closer to a running application. Has anyone had success with multiple axes scatter plot?


#2

It should just be go.Scatter not {go.Scatter.


#3

Had that initially but I gives me a syntax error, so that’s why I added the curly braces ( { and } ) based upon the multi axes examples. I now have:

'data': [
                go.Scatter(
                    x=df[df['continent'] == i]['gdp per capita'],
                    y=df[df['continent'] == i]['life expectancy'],
                    text=df[df['continent'] == i]['country'],
                    mode='markers',
                    opacity=0.7,
                    marker={
                        'size': 15,
                        'line': {'width': 0.5, 'color': 'white'}
                    },
                    name=i
                ) for i in df.continent.unique()
                go.Scatter(
                    x=df[df['continent'] == i]['gdp per capita'],
                    y=df[df['continent'] == i]['population'],
                    text=df[df['continent'] == i]['country'],
                    mode='markers',
                    opacity=0.7,
                    marker={
                        'size': 15,
                        'line': {'width': 0.5, 'color': 'white'}
                    },
                    name=i
                ) for i in df.continent.unique()
            ],

The syntax error is:

 File "graph_from_dataframe.py", line 33
    go.Scatter(
     ^
SyntaxError: invalid syntax

I just can’t seem to get the syntax for second scatter set (population) correct…


#4

Looks like an issue with python list conacentation. Try 'data': [ [go.Scatter(...) for i in ...] + [go.Scatter(...) for i in ...]]


#5

The hash() is a built-in python method, used to return a unique number . This can be applied to any user-defined object which won’t get changed once initialized. This property is used mainly in dictionary keys .

TypeError: unhashable type: ‘list’ usually means that you are trying to use a list as an hash argument. This means that when you try to hash an unhashable object it will result an error. For ex. when you use a list as a key in the dictionary , this cannot be done because lists can’t be hashed. The standard way to solve this issue is to cast a list to a tuple .