Trying to make a choropleth map in plotly using some data I have in a csv file. Have created the following map:
my choromap
This isn't a correct display of the data however. Here is an excerpt of my csv file:
China,2447
...
Trinidad And Tobago,2
Turkey,26
Ukraine,8
United Arab Emirates,97
United States of America,2008
Based on this I'd expected China to appear in a similar colour to that which the US has loaded in, however it looks the same as countries with values of less than 200. Does anyone know what the reason for this is?
Here's my full code for reference:
import pandas as pd
import plotly as py
df = pd.read_csv('app_country_data_minus_uk.csv')
data = [dict(type='choropleth',
locations = df['Country'],
locationmode = 'country names',
z = df['Applications'],
text = df['Country'],
colorbar = {'title':'Apps per country'},
colorscale = 'Jet',
reversescale = False
)]
layout = dict(title='Application Jan-June 2018',
geo = dict(showframe=False,projection={'type':'mercator'}))
choromap = dict(data = data,layout = layout)
red = py.offline.plot(choromap,filename='world.html')
per your comment I would make sure that china is indeed 2447 and not something like 244. I would also follow the plotly documentation although you example code works.
import plotly.plotly as py
import pandas as pd
df = pd.read_csv('app_country_data_minus_uk.csv')
data = [ dict(
type = 'choropleth',
locations = df['Country'],
locationmode = 'country names',
z = df['Applications'],
colorscale = 'Jet',
reversescale = False,
marker = dict(
line = dict (
color = 'rgb(180,180,180)',
width = 0.5
) ),
colorbar = dict(
autotick = False,
tickprefix = '',
title = 'Apps per country'),
) ]
layout = dict(
title = 'app_country_data_minus_uk',
geo = dict(
showframe = True,
showcoastlines = True,
projection = dict(
type = 'Mercator'
)
)
)
fig = dict( data=data, layout=layout )
py.iplot( fig, validate=False, filename='d3-world-map' )
or if you want to plot it offline:
import plotly.plotly as py
import pandas as pd
import plotly
df = pd.read_csv('app_country_data_minus_uk.csv')
data = [ dict(
type = 'choropleth',
locations = df['Country'],
locationmode = 'country names',
z = df['Applications'],
colorscale = 'Jet',
reversescale = False,
marker = dict(
line = dict (
color = 'rgb(180,180,180)',
width = 0.5
) ),
colorbar = dict(
title = 'Apps per country'),
) ]
layout = dict(
title = 'app_country_data_minus_uk',
geo = dict(
showframe = True,
showcoastlines = True,
projection = dict(
type = 'Mercator'
)
)
)
fig = dict( data=data, layout=layout )
plotly.offline.plot(fig,filename='world.html')
If you use iplot you will be able to edit the chart and see the data in plotly to make sure your data looks correct
Related
I want to show how many mma fighters each country has.This code is works. But USA has not any color.(USA has the greatest value)How can I fix it?
https://www.kaggle.com/firaterdemdogan/mma-practice
data = [ dict(
type = 'choropleth',
locations = index,
locationmode = 'country names',
z = values,
text = index,
#colorscale = [[0,'rgb(255, 255, 255)'],[1,'rgb(56, 142, 60)']],
#colorscale = [[0,'rgb(255, 255, 255)'],[1,'rgb(220, 83, 67)']],
colorscale = [[0,"rgb(5, 10, 172)"],[0.85,"rgb(40, 60, 190)"],[0.9,"rgb(70, 100, 245)"],\
[0.94,"rgb(90, 120, 245)"],[0.97,"rgb(106, 137, 247)"],[1,"rgb(220, 220, 220)"]],
autocolorscale = False,
reversescale = True,
marker = dict(
line = dict (
color = 'rgb(180,180,180)',
width = 0.5
) ),
colorbar = dict(
autotick = False,
tickprefix = '',
title = 'Countries Of Fighters'),
) ]
layout = dict(
title = 'Countries Of Fighters',
geo = dict(
showframe = False,
showcoastlines = True,
projection = dict(
type = 'Mercator'
)
)
)
fig = dict( data=data, layout=layout )
py.iplot( fig, validate=False)
fundamentally country is not normalised to standard values
have used https://restcountries.eu/#api-endpoints-name to get country ISO standard details. It's not quick but it works
now mma dataframe has two additional columns, isocountry - standardised name iso3code - standard 3 character code
there are still some countries that do not normalize
have not focused on formatting figures, just simple ones to demonstrate it works when country data has been standardised
import kaggle.cli
import sys, requests
import pandas as pd
from pathlib import Path
from zipfile import ZipFile
import plotly.express as px
# download data set
# https://www.kaggle.com/binduvr/pro-mma-fighters
sys.argv = [
sys.argv[0]
] + "datasets download binduvr/pro-mma-fighters".split(
" "
)
kaggle.cli.main()
zfile = ZipFile("pro-mma-fighters.zip")
dfs = {f.filename:pd.read_csv(zfile.open(f)) for f in zfile.infolist() }
mma = dfs['pro_mma_fighters.csv']
# country names are not clean...
def iso_dtl(c):
cmap = {}
res = requests.get(f"https://restcountries.eu/rest/v2/name/{c}")
if res.status_code==200:
if len(res.json())==1:
cmap = {"isocountry":res.json()[0]["name"], "iso3code":res.json()[0]["alpha3Code"]}
else:
df = pd.DataFrame(res.json()).sort_values("population", ascending=False).reset_index()
cmap = {"isocountry":df.loc[0,"name"], "iso3code":df.loc[0, "alpha3Code"]}
else:
cmap = {"isocountry":c, "iso3code":""}
return {**{"country":c}, **cmap}
dfcountry = pd.DataFrame([iso_dtl(c) for c in mma["country"].unique()])
mma = mma.merge(dfcountry, on="country")
px.bar(mma["isocountry"].value_counts()[:5]).show()
px.choropleth(mma["isocountry"].value_counts().reset_index(),
locations="index", locationmode="country names", color="isocountry")
I'm trying to plot the intensity of CO2 emissions per country using plotly ,
Most of the countries don't even exceed 10k, but the color range is from 0 to 35k , how do I change that?
Here's my code:
def enable_plotly_in_cell():
import IPython
from plotly.offline import init_notebook_mode
display(IPython.core.display.HTML('''<script src="/static/components/requirejs/require.js"></script>'''))
init_notebook_mode(connected=False)
data = dict(type = 'choropleth',
locations = fmmcgrf['Entity'],
locationmode = 'country names',
z = fmmcgrf['CO2'],
text = fmmcgrf['Entity'],
colorbar = {'title':'CO2'})
layout = dict(title = 'Co2',
geo = dict(showframe = False,
projection = {'type': 'winkel tripel'}))
map = go.Figure(data = [data], layout=layout)
enable_plotly_in_cell()
map.show()
I customized the color bar with the example from the official reference.
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/2014_world_gdp_with_codes.csv')
fig = go.Figure(data=go.Choropleth(
locations = df['CODE'],
z = df['GDP (BILLIONS)'],
text = df['COUNTRY'],
colorscale = 'Blues',
autocolorscale=False,
reversescale=True,
marker_line_color='darkgray',
marker_line_width=0.5,
colorbar_tickprefix = '$',
colorbar_tickvals=[0,10000,15000],# update
colorbar_title = 'GDP<br>Billions US$',
))
fig.update_layout(
title_text='2014 Global GDP',
geo=dict(
showframe=False,
showcoastlines=False,
projection_type='equirectangular'
),
)
fig.show()
I have been trying to create a Geoscatter Plot with Plotly where the marker size should indicate the number of customers (row items) in one city (zip_city). I based my code on two templates from the Plotly documentation: United States Bubble Map and the aggregation part Mapping with Aggregates.
I managed to put together a code that does what I want, except for one drawback: when I hover over a bubble, I would like to see the name of the city plus number of customers (the result from the aggregation), so something like Aguadilla: 2. Can you help me on how to do this?
Here is my code (as a beginner with plotly, I am also open to code improvements):
import plotly.offline as pyo
import pandas as pd
df = pd.DataFrame.from_dict({'Customer': [111, 222, 555, 666],
'zip_city': ['Aguadilla', 'Aguadilla', 'Arecibo', 'Wrangell'],
'zip_latitude':[18.498987, 18.498987, 18.449732,56.409507],
'zip_longitude':[-67.13699,-67.13699,-66.69879,-132.33822]})
data = [dict(
type = 'scattergeo',
locationmode = 'USA-states',
lon = df['zip_longitude'],
lat = df['zip_latitude'],
text = df['Customer'],
marker = dict(
size = df['Customer'],
line = dict(width=0.5, color='rgb(40,40,40)'),
sizemode = 'area'
),
transforms = [dict(
type = 'aggregate',
groups = df['zip_city'],
aggregations = [dict(target = df['Customer'], func = 'count', enabled = True)]
)]
)]
layout = dict(title = 'Customers per US City')
fig = dict( data=data, layout=layout )
pyo.plot( fig, validate=False)
Update:
Can I access the result of the transforms argument directly in the data argument to show the number of customers per city?
You can create a list, that will contains what you want and then set text=list in data. Also do not forget specify hoverinfo='text'.
I am updated your code, so try this:
import pandas as pd
import plotly.offline as pyo
df = pd.DataFrame.from_dict({'Customer': [111, 222, 555, 666],
'zip_city': ['Aguadilla', 'Aguadilla', 'Arecibo', 'Wrangell'],
'zip_latitude':[18.498987, 18.498987, 18.449732,56.409507],
'zip_longitude':[-67.13699,-67.13699,-66.69879,-132.33822]})
customer = df['Customer'].tolist()
zipcity = df['zip_city'].tolist()
list = []
for i in range(len(customer)):
k = str(zipcity[i]) + ':' + str(customer[i])
list.append(k)
data = [dict(
type = 'scattergeo',
locationmode = 'USA-states',
lon = df['zip_longitude'],
lat = df['zip_latitude'],
text = list,
hoverinfo = 'text',
marker = dict(
size = df['Customer'],
line = dict(width=0.5, color='rgb(40,40,40)'),
sizemode = 'area'
),
transforms = [dict(
type = 'aggregate',
groups = df['zip_city'],
aggregations = [dict(target = df['Customer'], func = 'count', enabled = True)]
)]
)]
layout = dict(title = 'Customers per US City')
fig = dict(data=data, layout=layout)
pyo.plot(fig, validate=False)
I am working on choropleth using plotly in Jupyter Notebook.I want to plot choropleth but its showing me empty output.I am working with offline plotly.In html its genrated chart successfuly but when i tried offline it shows me empty output.please tell me how i solve this error.
here is my code
from plotly.graph_objs import *
from plotly.offline import download_plotlyjs, init_notebook_mode, iplot
from plotly.offline.offline import _plot_html
init_notebook_mode(connected=True)
for col in state_df.columns:
state_df[col] = state_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)']]
state_df['text'] = state_df['StateCode'] + '<br>' +'TotalPlans '+state_df['TotalPlans']
data = [ dict(
type='choropleth',
colorscale = scl,
autocolorscale = False,
locations = state_df['StateCode'],
z = state_df['TotalPlans'].astype(float),
locationmode = 'USA-states',
text = state_df['text'],
marker = dict(
line = dict (
color = 'rgb(255,255,255)',
width = 2
)
),
colorbar = dict(
title = "Millions USD"
)
) ]
layout = dict(
title = 'Plan by States',
geo = dict(
scope='usa',
projection=dict( type='albers usa' ),
showlakes = True,
lakecolor = 'rgb(255, 255, 255)',
),
)
fig = dict(data=data, layout=layout)
plotly.offline.iplot(fig)
You are passing a dictionary to iplot which in contradiction to the documentation can handle only Figure objects and not dictionaries.
Try
fig = Figure(data=[data], layout=layout)
and it should work.
Trying to use plotly to combine this line graph (that's already stacked):
import plotly
import plotly.graph_objs as plgo
#... Some Code
max = plgo.Scatter(x = day_times_str, y = max_val , name = "Max")
min = plgo.Scatter(x = day_times_str, y = min_val, name = "Min")
layout_opts = plgo.Layout(
xaxis = dict(title = 'xaxis'),
yaxis = dict(title = 'yaxis', rangemode = "tozero"),
)
figure1 = plgo.Figure(
data = [max, min],
layout = layout_opts,
)
and a map that shows location above this line graph...
#Assume geo_coord is a dataframe of coordinates, with columns 'lat', 'long' and 'text'
geo_data = [
plgo.Scattermapbox(
lat = geo_coord['lat'],
lon = geo_coord['lon'],
text = geo_coord['text'],
marker = dict(
color = geo_coord['text'],
size = 12,
),
mode = 'markers'
)
]
geo_layout = plgo.Layout(
autosize=True,
hovermode='closest',
mapbox=dict(
accesstoken= GMapsAPIHelper.MAPBOX_TOKEN, #Constant stored in global object
bearing=0,
pitch=0,
center=dict(
lat=49.04,
lon=-122.7
), #Modify by project details
zoom= 13
),
)
figure2 = dict(data = geo_data, layout = geo_layout)
plotly.offline.plot takes only 1 figure or set of data and I cannot pass in a list for graphing. I have tried using append_trace but because I've defined x and y axes in the line graph layout, this causes an error for the map, as follows:
File "C:\Anaconda2\lib\site-packages\plotly\graph_objs\graph_objs.py", line 934, in append_trace
trace['xaxis'] = ref[0]
TypeError: list indices must be integers, not str
Any help in solving this issue is appreciated.