Choropleth world map not showing all countries - python

I wanted to make a choropleth world map, which shows the hits(number of searches) of a word, on a World map.
Following is the code:
import plotly
import plotly.offline
import pandas as pd
df = pd.read_excel('F:\\Intern\\csir\\1yr\\news\\region_2016_2017.xlsx')
df = df.query('keyword==["addiction"]')
scl = [[0.0, 'rgb(242,240,247)'],[0.2, 'rgb(218,218,235)'],[0.4, 'rgb(188,189,220)'],\
[0.6, 'rgb(158,154,200)'],[0.8, 'rgb(117,107,177)'],[1.0, 'rgb(84,39,143)']]
data = [dict(
type='choropleth',
colorscale=scl,
locations = df['location'],
z = df['hits'].astype(int),
locationmode = "country names",
autocolorscale = False,
reversescale = False,
marker = dict(
line = dict (
color = 'rgb(180,180,180)',
width = 0.5)),
colorbar = dict(
autotick = False,
title = 'Hits'),)]
layout = dict(
title = 'Addiction keyword 1yr analysis',
geo = dict(
showframe = False,
showcoastlines = False,
projection = dict(
type = 'Mercator'
)
)
)
fig = dict(data = data,layout = layout)
plotly.offline.plot(fig,validate=False,filename = 'd3-world-map.html')
And the plotted map is:
As one can see clearly, many countries are missing. This may be due to the fact that many countries didn't have entries which explicitly stated that they have zero hits.
I don't want to explicitly do that with my data. Is there any other way out of this? So that we can see all of the countries.
Data set can be found here.
Note that the dataset that I've linked is an .csv file whereas the file used in the program is an .xlsx version of the file.

You need to turn on country outlines under layout...
"geo":{
"countriescolor": "#444444",
"showcountries": true
},

Related

Hover callback problem - doesn't display dataframe

I am new to Python and have limited coding experience, so any input and advice is deeply appreciated.
I have created a dynamic choropleth map which includes a scatter_geo plot that overlays the relevant areas.
I am trying create a hover callback so that when I hover over one of these points, a dataframe appears that is indexed according to the point id (the first column in the defined dataframe). Essentially, it is a choropleth map equivalent of this example: https://plotly.com/python/v3/cars-exploration/ but without using FigureWidget.
I keep getting stuck on the hover callback function; no dataframe displays when I hover. Below is the code I have so far.
license_df1 = pd.read_excel(lic, "Primary Holdings by License", dtype = "str").fillna('')
license_df2 = pd.read_excel(lic, "Secondary Holdings by License", dtype = "str").fillna('')
### CREATE PLOTTING FEATURES ###
app = dash.Dash(__name__, suppress_callback_exceptions = True)
app.css.config.serve_locally = True
app.scripts.config.serve_locally = True
app.layout = html.Div([
html.P("Spectrum Band:"), # Create Toggle Items between spectrum bands
dcc.RadioItems(id = "Band", options=[{'value': x, 'label':x} for x in df1_band], value = df1_band[0]),
dcc.Graph(id = "choropleth"),
dash_table.DataTable(id = "table")])
#app.callback(
Output("choropleth", "figure"),
[Input("Band", "value")])
def build_graph(value):
if value == '600 MHz':
df1_600 = df1[(df1["Band"] == "600 MHz")]
fig1 = px.choropleth(df1_600, geojson = PEAs, featureidkey = "properties.PEA_Num",
locations = 'PEA # ', hover_data = {'PEA # ': False}, scope = "usa")
# Overlay Geographic Scatter Plot for interactive functionality
fig1b = px.scatter_geo(df1_600, geojson = PEAs, featureidkey = "properties.PEA_Num",
locations = 'PEA # ', hover_name = 'Market', scope = "usa")
fig1.add_trace(fig1b.data[0])
fig1.update_traces(showlegend = False)
fig1.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
return fig1
elif value == '3.7 GHz':
df1_3700 = df1[(df1["Band"] == "3.7 GHz")]
fig2 = px.choropleth(df1_3700, geojson = PEAs, featureidkey = "properties.PEA_Num",
locations = 'PEA # ', hover_data = {'PEA # ': False}, scope = "usa")
# Overlay Geographic Scatter Plot for interactive functionality
fig2b = px.scatter_geo(df1_3700, geojson = PEAs, featureidkey = "properties.PEA_Num",
locations = 'PEA # ', hover_name = 'Market', scope = "usa")
fig2.add_trace(fig2b.data[0])
fig2.update_traces(showlegend = False)
fig2.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
return fig2
#app.callback(
Output("table", "data"),
[Input("fig1", "hover_data")]) # WHERE I AM HAVING TROUBLE
def disp_license1(hover_data):
table_vals = license_df1.iloc[points.point_inds[0]].to_frame().to_html()
return table_vals
app.run_server(debug = True)

How to randomly select colors in plotly python graph

I have the following data lists:
date = ['2019-01-01', '2019-01-18', '2019-02-03']
value1 = [6798.0, 436.0, 348.0]
value2 = [500.0, 455.0, 348.0]
From these lists I generate a line graph using the plotly library, this way:
trace_1 = go.Scatter(x = date,
y = value1,
mode = 'markers+lines',
marker_color='rgb(152, 0, .8)',
name = '1')
trace_2 = go.Scatter(x = date,
y = value2,
mode = 'markers+lines',
marker_color='rgb(0, 0, .8)',
name = '2')
data_total = [trace_1, trace_2]
fig = go.Figure(data=data_total, layout=layout)
py.iplot(fig)
The graphic is working perfectly and the lines are in different colors. However, I would like the line colors, instead of manual as I did, to be automatically generated randomly.
Following this tutorial: https://www.kite.com/python/answers/how-to-generate-random-colors-in-matplotlib-in-python
I tried to do:
colors = np.random.rand(1,3)
trace_1 = go.Scatter(x = date,
y = value1,
mode = 'markers+lines',
marker_color = colors,
name = '1')
trace_2 = go.Scatter(x = date,
y = value2,
mode = 'markers+lines',
marker_color = colors,
name = '2')
data_total = [trace_1, trace_2]
fig = go.Figure(data=data_total, layout=layout)
py.iplot(fig)
But this code doesn't work.
You should only need to comment out marker_color. Many plotting libraries (plotly included) tend to automatically assign colors.

Not able to view US-states heatmap

I have written the following code to heat heatmap of US-States. But I am unable to get the output image in Google Colab.
State codes are two alphabet codes for a particular state of the US.
temp = pd.DataFrame(project_data.groupby("school_state")["project_is_approved"].apply(np.mean)).reset_index()
temp.columns = ['state_code', 'num_proposals']
scl = [[0.0, 'rgb(242,240,247)'],[0.2, 'rgb(218,218,235)'],[0.4, 'rgb(188,189,220)'],\
[0.6, 'rgb(158,154,200)'],[0.8, 'rgb(117,107,177)'],[1.0, 'rgb(84,39,143)']]
data = [ dict(
type='choropleth',
colorscale = scl,
autocolorscale = False,
locations = temp['state_code'],
z = temp['num_proposals'].astype(float),
locationmode = 'USA-states',
text = temp['state_code'],
marker = dict(line = dict (color = 'rgb(255,255,255)',width = 2)),
colorbar = dict(title = "% of pro")
) ]
layout = dict(
title = 'Project Proposals % of Acceptance Rate by US States',
geo = dict(
scope='usa',
projection=dict( type='albers usa' ),
showlakes = True,
lakecolor = 'rgb(255, 255, 255)',
),
)
fig = dict(data=data, layout=layout)
offline.iplot(fig, filename='us-map-heat-map')
I have imported following libraries:
from chart_studio import plotly
import plotly.offline as offline
import plotly.graph_objs as go
offline.init_notebook_mode()
from collections import Counter
import chart_studio.plotly as py
Try the following code with your data:
(I tried putting your variables in the correct spots)
choropleth = go.Choropleth(
locations=temp['state_code'],
locationmode='USA-states',
z = temp['num_proposals'].astype(float),
zmin = 0,
zmax = max(temp['num_proposals'].astype(float)),
colorscale=scl,
autocolorscale=False,
text='Proposals',
marker_line_color='white',
colorbar_title="% Acceptance Rate"
)
fig = go.Figure(data=choropleth)
fig.update_layout(
title_text='Project Proposals % of Acceptance Rate by US States',
geo = dict(
scope='usa',
projection=go.layout.geo.Projection(type = 'albers usa'),
showlakes=True,
lakecolor='rgb(255, 255, 255)'),
)
fig.show()
This code works by creating the Plotly Choropleth Graph Object with your data, then loading that object into a Plotly Figure Graph Object, then updating the layout (for proper titles and zooms), and finally displaying the figure.

Plotting categorial groupings in bokeh with geopandas not working? (Problem with CategoricalColorMapper)

I'm having problems plotting groupings of countries on a world map using Bokeh in combination with the geopandas package. What I want to do is colour each country in a group with a certain colour on the map. The groupings are saved in the dataframe "dataset", which is merged with the geopandas geographical info, converted to json and fed to the mapping functions. (Code below.)
The interesting thing is that no error is generated, Bokeh even reports that "BokehJS 1.4.0 successfully loaded", but no chart is shown.
I am quite convinced that the problem is with my implementation of the CategoricalColorMapper. This is evident since if I change the color mapper to to linear color mapper, the code works perfectly.
This code does not work:
from bokeh.palettes import viridis
from bokeh.models import FactorRange
dataset = gdf.merge(dataset, left_on = 'country', right_on = 'location', how = 'left')
#gdf is geopandas geo info dataframe
#Read data to json
dataset_json = json.loads(dataset.to_json())
#Convert to str like object
dataset_json_data = json.dumps(dataset_json)
#Input GeoJSON source that contains features for plotting.
geosource = GeoJSONDataSource(geojson = dataset_json_data)
catValues=list(dataset["val"].dropna().unique().astype("str"))
palette=viridis(len(catValues))
print("Palette len:", len(palette))
print("Factors:", len(catValues))
print(dataset)
color_mapper = CategoricalColorMapper(palette = palette , factors=catValues)
#Create figure object.
p = figure(title = title_string, plot_height = 600 , plot_width = 950, toolbar_location = None)
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None
#Add patch renderer to figure.
p.patches('xs','ys', source = geosource, fill_color = {'field' :'val', 'transform' : color_mapper})
#Display figure inline in Jupyter Notebook.
output_notebook()
#Display figure.
show(p)
Calling the function prints the following, but non map is shown. The number of colors and categories seems fine to me?
Palette len: 118
Factors: 118
BokehJS 1.4.0 successfully loaded.
Replacing only the color mapper works perfectly. This code works:
def plot_map(dataset, title_string = ""):
dataset = gdf.merge(dataset, left_on = 'country', right_on = 'location', how = 'left')
#Read data to json
dataset_json = json.loads(dataset.to_json())
#Convert to str like object
dataset_json_data = json.dumps(dataset_json)
#Input GeoJSON source that contains features for plotting.
geosource = GeoJSONDataSource(geojson = dataset_json_data)
#Define a sequential multi-hue color palette.
palette = brewer['OrRd'][7]
#Reverse color order so that dark blue is highest obesity.
palette = palette[::-1]
#Instantiate LinearColorMapper that linearly maps numbers in a range, into a sequence of colors.
color_mapper = LinearColorMapper(palette = palette, low = dataset.val.min(), high = dataset.val.max())
#Define custom tick labels for color bar.
#tick_labels = {'0': '0', '1': '1', '2':'2', '3':'3', '4':'4', '5':'5', '6':'6','7':'7'}
#Create color bar.
color_bar = ColorBar(color_mapper=color_mapper, label_standoff=7,width = 500, height = 20,
border_line_color=None,location = (0,0), orientation = 'horizontal', major_label_overrides = tick_labels)
#Create figure object.
p = figure(title = title_string, plot_height = 600 , plot_width = 950, toolbar_location = None)
p.xgrid.grid_line_color = None
p.ygrid.grid_line_color = None
#Add patch renderer to figure.
p.patches('xs','ys', source = geosource, fill_color = {'field' :'val', 'transform' : color_mapper},
line_color = 'black', line_width = 0.25, fill_alpha = 1)
#Specify figure layout.
p.add_layout(color_bar, 'below')
#Display figure inline in Jupyter Notebook.
output_notebook()
#Display figure.
show(p)

Python Plotly Error

It seems that the example code on the plotly website for choropleth maps is out of date and no longer works.
The error I'm getting is:
PlotlyError: Invalid 'figure_or_data' argument. Plotly will not be able to properly parse the resulting JSON. If you want to send this 'figure_or_data' to Plotly anyway (not recommended), you can set 'validate=False' as a plot option.
Here's why you're seeing this error:
The entry at index, '0', is invalid because it does not contain a valid 'type' key-value. This is required for valid 'Data' lists.
Path To Error:
['data'][0]
The code that I'm trying to run is shown below. It is copied as-is from the plotly website. Anyone have any ideas as to how I can fix it?
import plotly.plotly as py
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2011_us_ag_exports.csv')
for col in df.columns:
df[col] = df[col].astype(str)
scl = [[0.0, 'rgb(242,240,247)'],[0.2, 'rgb(218,218,235)'],[0.4, 'rgb(188,189,220)'],\
[0.6, 'rgb(158,154,200)'],[0.8, 'rgb(117,107,177)'],[1.0, 'rgb(84,39,143)']]
df['text'] = df['state'] + '<br>' +\
'Beef '+df['beef']+' Dairy '+df['dairy']+'<br>'+\
'Fruits '+df['total fruits']+' Veggies ' + df['total veggies']+'<br>'+\
'Wheat '+df['wheat']+' Corn '+df['corn']
data = [ dict(
type='choropleth',
colorscale = scl,
autocolorscale = False,
locations = df['code'],
z = df['total exports'].astype(float),
locationmode = 'USA-states',
text = df['text'],
marker = dict(
line = dict (
color = 'rgb(255,255,255)',
width = 2
)
),
colorbar = dict(
title = "Millions USD"
)
) ]
layout = dict(
title = '2011 US Agriculture Exports by State<br>(Hover for breakdown)',
geo = dict(
scope='usa',
projection=dict( type='albers usa' ),
showlakes = True,
lakecolor = 'rgb(255, 255, 255)',
),
)
fig = dict(data=data, layout=layout)
url = py.plot(fig, filename='d3-cloropleth-map')
fig should be of the Figure type. Use the Choropleth graph object:
import plotly.graph_objs as go
...
data = [go.Choropleth(
colorscale = scl,
autocolorscale = False,
locations = df['code'],
z = df['total exports'].astype(float),
locationmode = 'USA-states',
text = df['text'],
marker = dict(
line = dict(
color = 'rgb(255,255,255)',
width = 2)),
colorbar = dict(
title = "Millions USD")
)]
...
fig = go.Figure(data=data, layout=layout)
...

Categories