Trying to run the following code, and it returns following error in Power BI:
ValueError: Invalid value of type 'builtins.float' received for the 'opacity' property of scattergeo. Received value: nan
The 'opacity' property is a number and may be specified as: - An int or float in the interval [0, 1].
From the 'cnt' column, all values are whole numbers ranging from 1 to 35.
Also. When I replace the opacity line with = 1. It says Power BI cannot create a visual, and it opens up in my browser with a working visual.... Any idea why it wont load in Power BI, but will load in my browser working as intended?
Code Below, any and all help is greatly appreciated!
# dataset = pandas.DataFrame(start_lat, start_lon, end_lat, end_lon, cnt, lat, long)
# dataset = dataset.drop_duplicates()
# Paste or type your script code here:
import plotly.graph_objects as go
import pandas as pd
import os
os.chdir(r'C:\Users\myself\Desktop\data_files\py_docs')
df_dcs = (dataset)
df_lanes = (dataset)
fig = go.Figure()
fig.add_trace(go.Scattergeo(
locationmode = 'USA-states',
lon = df_dcs['long'],
lat = df_dcs['lat'],
hoverinfo = 'text',
text = df_dcs['location'],
mode = 'markers',
marker = dict(
size = 4,
color = 'rgb(255, 153, 51)',
line = dict(
width = 3,
color = 'rgba(68, 68, 68, 0)'
)
)))
lanes = []
for i in range(len(df_lanes)):
fig.add_trace(
go.Scattergeo(
locationmode = 'USA-states',
lon = [df_lanes['start_lon'][i], df_lanes['end_lon'][i]],
lat = [df_lanes['start_lat'][i], df_lanes['end_lat'][i]],
mode = 'lines',
line = dict(width = 3,color = 'orange'),
opacity = float(df_lanes['cnt'][i]) / float(df_lanes['cnt'].max()),
)
)
fig.update_layout(
title_text = 'Route Lanes',
showlegend = False,
geo = dict(
scope = 'north america',
projection_type = 'azimuthal equal area',
showland = True,
landcolor = 'rgb(243, 243, 243)',
countrycolor = 'rgb(204, 204, 204)',
),
)
fig.show()```
Related
I am working on a plotter for Finite Element Method solutions. I decided to use the Plotly library because of the carpet plots. I have my data to plot and this is my result:
Flow over NACA0012
Each element is represented as a Carpet, and for each carpet the solution is shown as a Countourcarpet. Everything is in place, but the rendering is too slow and the interactive interface is therefore nearly useless. Is there a way to enhance the performance of the rendering? I have read about different renderers in Plotly, but the plot just does not open. Is there a a way to speed up the rendering? Surely I will have to manage larger dataset. In this example I am using 740 carpets.
These are the Contourcarpet settings:
fig.add_trace(go.Contourcarpet(
a = a,
b = b,
z = u, # Sution correspondent at (a,b) parametric location
showlegend = showLegendFlag,
name = "Density",
legendgroup = "Density",
autocolorscale = False,
colorscale = "Inferno",
autocontour = False,
carpet = str(e), # The carpet on which to plot the solution is
# referenced as a string number
contours = dict(
start = start1, # Min value
end = end1, # Max value
size = abs(end1-start1) / countour_number, # Plot colour discretization
showlines = False
),
line = dict(
smoothing = 0
),
colorbar = dict(
len = 0.4,
y = 0.25
)
))
And these are the layout settings:
fig.update_layout(
plot_bgcolor="#FFF",
yaxis = dict(
zeroline = False,
range = [-1.800,1.800],
showgrid = False
),
dragmode = "pan",
height = 700,
xaxis = dict(
zeroline = False,
scaleratio = 1,
scaleanchor = 'y',
range = [-3.800,3.800],
showgrid = False
),
title = "Flow over NACA 0012",
hovermode = "closest",
margin = dict(
r = 80,
b = 40,
l = 40,
t = 80
),
width = 900
)
fig.show()
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")
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
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)
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.