Black Lives Matter. Please consider donating to Black Girls Code today.

The problem with displaying data on a world map from a database

When loading data from a csv file, data is displayed correctly, but when i using the same data, but from the database, there is a problem with displaying data on a world map. Analysis of other data and graphing is correct. I tried changing the data type of coordinates, but it didn’t affect. Maybe I’m missing something explicit, but i still an inexperienced user.
This is how I get data from the csv:

terrorism = pd.read_csv('F:/data/terrorism-analysis/apps/data/globalterrorism.csv',
                        encoding='latin-1', low_memory=False, 
                        usecols=['iyear', 'imonth', 'iday', 'country_txt', 'city', 'longitude', 'latitude', 
                       'nkill', 'nwound', 'summary', 'target1', 'gname'])

And this is how I get data from the database:

connection = pymysql.connect(host='localhost',
                             user='root',
                             password='*****',                             
                             db='terrorism_bd',
                             charset='utf8mb4')
try:
    sql = "SELECT iyear, imonth, iday, country_txt, city, longitude, latitude, nkill, nwound, summary, target1, gname FROM maintable "
    terrorism = pd.read_sql(sql, connection)              
finally:      
    connection.close()

In the case of using data from the database when choosing a country to display on the world map (in my case, terrorist acts and their coordinates), the following error is displayed:

127.0.0.1 - - [23/Jan/2020 02:16:53] "POST /_dash-update-component HTTP/1.1" 200 -
127.0.0.1 - - [23/Jan/2020 02:16:59] "POST /_dash-update-component HTTP/1.1" 200 -
[2020-01-23 02:16:59,103] ERROR in app: Exception on /_dash-update-component [POST]
Traceback (most recent call last):
  File "C:\Users\Andrey\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 2446, in wsgi_app
    response = self.full_dispatch_request()
  File "C:\Users\Andrey\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1951, in full_dispatch_request
    rv = self.handle_user_exception(e)
  File "C:\Users\Andrey\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1820, in handle_user_exception
    reraise(exc_type, exc_value, tb)
  File "C:\Users\Andrey\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\_compat.py", line 39, in reraise
    raise value
 ...
  File "C:\Users\Andrey\AppData\Local\Programs\Python\Python37-32\lib\site-packages\flask\app.py", line 1935, in dispatch_request
    return self.view_functions[rule.endpoint](**req.view_args)
  File "C:\Users\Andrey\AppData\Local\Programs\Python\Python37-32\lib\site-packages\dash\dash.py", line 1404, in dispatch
    response.set_data(self.callback_map[output]["callback"](*args))
  File "C:\Users\Andrey\AppData\Local\Programs\Python\Python37-32\lib\site-packages\dash\dash.py", line 1284, in add_context
    output_value = func(*args, **kwargs)  # %% callback invoked %%
  File "f:\data\terrorism-master\apps\world.py", line 144, in countries_on_map
    for c in countries],
  File "f:\data\terrorism-master\apps\world.py", line 144, in <listcomp>
    for c in countries],
  File "f:\data\terrorism-master\apps\world.py", line 132, in <listcomp>
    'data': [go.Scattergeo(lon=[x + random.gauss(0.04, 0.03) for x in df[df['country_txt'] == c]['longitude']],
TypeError: can only concatenate str (not "float") to str

Another piece of code referenced by the error:

@app.callback(Output('map_world', 'figure'),
             [Input('countries', 'value'), Input('years', 'value')])
def countries_on_map(countries, years):
    df = terrorism[terrorism['country_txt'].isin(countries) & terrorism['iyear'].between(years[0], years[1])]
    
    return {
        'data': [go.Scattergeo(lon=[x + random.gauss(0.04, 0.03) for x in df[df['country_txt'] == c]['longitude']],
                               lat=[x + random.gauss(0.04, 0.03) for x in df[df['country_txt'] == c]['latitude']],
                               name=c,
                               hoverinfo='text',
                               marker={'size': 9, 'opacity': 0.65, 'line': {'width': .2, 'color': '#cccccc'}},
                               hovertext=df[df['country_txt'] == c]['city'].astype(str) + ', ' + df[df['country_txt'] == c]['country_txt'].astype(str)+ '<br>' +
                                         [dt.datetime.strftime(d, '%d %b, %Y') for d in df[df['country_txt'] == c]['date']] + '<br>' +
                                         'Perpetrator: ' + df[df['country_txt'] == c]['gname'].astype(str) + '<br>' +
                                         'Target: ' + df[df['country_txt'] == c]['target1'].astype(str) + '<br>' + 
                                         'Deaths: ' + df[df['country_txt'] == c]['nkill'].astype(str) + '<br>' +
                                         'Injured: ' + df[df['country_txt'] == c]['nwound'].astype(str) + '<br><br>' + 
                                         ['<br>'.join(textwrap.wrap(x, 40)) if not isinstance(x, float) else '' for x in df[df['country_txt'] == c]['summary']])
                 for c in countries],
        'layout': go.Layout(title='Terrorist Attacks ' + ', '.join(countries) + '  ' + ' - '.join([str(y) for y in years]),
                            font={'family': 'Palatino'},
                            titlefont={'size': 22},
                            paper_bgcolor='#eeeeee',
                            plot_bgcolor='#eeeeee',
                            width=1420,
                            height=650,
                            annotations=[{'text': 'Data: START Consortium', 'x': .2, 'y': -.13, 'showarrow': False}],                            
                            geo={'showland': True, 'landcolor': '#eeeeee',
                                 'countrycolor': '#cccccc',
                                 'showsubunits': True,
                                 'subunitcolor': '#cccccc',
                                 'subunitwidth': 5,
                                 'showcountries': True,
                                 'oceancolor': '#eeeeee',
                                 'showocean': True,
                                 'showcoastlines': True, 
                                 'showframe': False,
                                 'coastlinecolor': '#cccccc',
                                 'lonaxis': {'range': [df['longitude'].min()-1, df['longitude'].max()+1]},
                                 'lataxis': {'range': [df['latitude'].min()-1, df['latitude'].max()+1]}
                                              })
    }

Please help me figure out what the error is and how to solve it.

Hi @AndreyGl welcome to the forum! I have to guess without having the data, but it’s possible that the data in your csv are opened as numerical values while when you retrieve them from the database they are strings (of numerical values, but considered as strings by pandas). Does that sound plausible? You can print a part in the dataframe in your app to inspect what is going on, and you can also print df['longitude'].dtype to check the type of the column.

Thank you for responding. I use data from the Global Terrorism Database (https://www.kaggle.com/START-UMD/gtd).
I recreated the database, maybe it was in it. Now when outputting from a file csv and database, the field longitude and latitude are of data type float64. But now another error is displayed:

  File "C:\Users\Andrey\AppData\Local\Programs\Python\Python37-32\lib\textwrap.py", line 351, in wrap
    chunks = self._split_chunks(text)
  File "C:\Users\Andrey\AppData\Local\Programs\Python\Python37-32\lib\textwrap.py", line 337, in _split_chunks
    text = self._munge_whitespace(text)
  File "C:\Users\Andrey\AppData\Local\Programs\Python\Python37-32\lib\textwrap.py", line 154, in _munge_whitespace
    text = text.expandtabs(self.tabsize)
AttributeError: 'NoneType' object has no attribute 'expandtabs'
127.0.0.1 - - [23/Jan/2020 14:42:51] "POST /_dash-update-component HTTP/1.1" 500 -
127.0.0.1 - - [23/Jan/2020 14:42:51] "POST /_dash-update-component HTTP/1.1" 200 -

Data opens as numerical values, sort of like:

       iyear  imonth  iday         country_txt           city  ...  nkill  nwound  summary                     target1                                      gname     
0       1970       7     2  Dominican Republic  Santo Domingo  ...    1.0     0.0     None                Julio Guzman                                     MANO-D     
1       1970       0     0              Mexico    Mexico city  ...    0.0     0.0     None     Nadine Chaval, daughter         23rd of September Communist League     
2       1970       1     0         Philippines        Unknown  ...    1.0     0.0     None                    Employee                                    Unknown     
3       1970       1     0              Greece         Athens  ...    NaN     NaN     None                U.S. Embassy                                    Unknown     
4       1970       1     0               Japan        Fukouka  ...    NaN     NaN     None              U.S. Consulate                                    Unknown     
...      ...     ...   ...                 ...            ...  ...    ...     ...      ...                         ...                                        ...     
11551   1980       7    29           Guatemala        Unknown  ...   37.0     NaN     None         Military Detachment                       Left-Wing Guerrillas     
11552   1980       7    30             Austria         Vienna  ...    0.0     8.0     None        Near Iranian Embassy                           Iraqi extremists     
11553   1980       7    30                Iran          Ahvaz  ...    7.0    30.0     None     Neufle Le Chateau Hotel                                    Unknown     
11554   1980       7    30               Italy          Milan  ...    0.0     0.0     None  City Hall (Palazzo Marino)  Revolutionary Committee for Counter Force     
11555   1980       7    30             Lebanon         Beirut  ...    2.0     5.0     None                   on street                                    Unknown     

[11556 rows x 12 columns]

Can someone help and advise about my mistake?

I hope this is not condemned here - BUMP

Hey @AndreyGl, the error message says that the object on which you are calling textwrap.wrap is None. This must happen in the one place where you call textwrap.wrap, inside the hovertext. I suggest that you write another line to print what is inside df[df['country_txt'] == c]['summary']] because it could be None. Generally speaking it’s useful to print things when you get errors.

Thanks for your help)