Interactive Choropleth using plotly & ipywidgets in python - python

I am trying to create an interactive choropleth using Plotly and ipywidgets for the dataframe which the head looks like the one shown below.
Data1.head()
The plot sums the values for all the available dates in the dataframe for each county.
Output for available FIPS (aggregated values)
I want to filter the values for a particular date using a dropdown menu and plot the values corresponding to this date.
import matplotlib.pyplot as plt
from ipywidgets import interact, interactive, fixed, interact_manual
import ipywidgets as widgets
from plotly import *
import plotly.figure_factory as ff
import plotly.graph_objects as go
date = widgets.Dropdown(
options=['All'] + Data1.date.unique().tolist(),
value='All',
description='Date:',
)
# date = Data1['date'][1] # If I use this instead of the widget defined above, the code works (at the cost of interactivity)
def func(date):
values = Data1[Data1['date']== date]['Infected'].tolist()
fips = Data1[Data1['date']== date]['Fips'].tolist()
colorscale = [
'rgb(193, 193, 193)',
'rgb(239,239,239)',
'rgb(195, 196, 222)',
'rgb(144,148,194)',
'rgb(101,104,168)',
'rgb(65, 53, 132)'
]
fig = ff.create_choropleth(
fips=fips, values=values, scope=['IL'],
binning_endpoints=[14348, 63983, 134827, 426762, 2081313], colorscale=colorscale,
county_outline={'color': 'rgb(255,255,255)', 'width': 0.5}, round_legend_values=True,
legend_title='Infected cases by County', title='Illinois State'
)
fig.layout.template = None
fig.show()
interactive(func, date= date)
I am able to get the dropdown menu using this code, but it does not print the plot.
Alternatively, I tried to hardcode the date (commented in code) and it did return the plot for the specific date, at the loss of interactivity.
Can someone help me to get the plot where I can let the user choose a date from the dropdown menu and plot the choropleth correspondingly?

Related

jupyter notebook display plots as separate output instead of updating existing one

I'd like to draw interactive plot and dropdown winget. For this aim I use the following code in my jupyter notebook:
import ipywidgets as widgets
import plotly.graph_objects as go
import pandas as pd
df = pd.DataFrame({'timestamp' : [1,2,3,4,5,6], 'close' : [11,22,33,44,55,66], 'open' : [111,222,333,444,555,666]})
def plot(feature):
fig = go.Figure(data=go.Scatter(x = df['timestamp'].values, y = df[feature].values),
layout_title_text = feature
)
fig.show()
_ = widgets.interact(plot, feature = ['close', 'open'])
Every time when I select value in dropdown box the corresponding plot is displayed in separate output - but I'd like to update existing:
PLease explain how to fix this issue

slider for choropleth map plotly shows error - <ipython-input-17-c5022c9e0aab>:13: SettingWithCopyWarning:

I am trying to add a slider for my choropleth map using plotly. I have been unable to see the map in google colab but jupyter notebook has worked fine.
I have a dataset with values for each country of the world over a period of years. I want to make a slider underneath so you can scroll through the years and see the colours change. I have been able to get data from one year, but I cannot get the slider to appear under my map, and I get a large pink error message saying the value is trying to be set on a copy of a slice from a DataFrame.
Is there anything I can do to fix this? Please find attached my code
pip install chart-studio
import pandas as pd
import chart_studio.plotly as py
import plotly.offline as po
import matplotlib.pyplot as plt
%matplotlib inline
import plotly
import plotly.graph_objs as go
import plotly.offline as offline
from plotly.graph_objs import *
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, pilot
df=pd.read_csv("https://raw.githubusercontent.com/jamesjeffery77/jamesjeffery77.github.io/main/share-electricity-low-carbon_fullDataset.csv")
year=1985
### create empty list for data object:
data_slider = []
# Populate data object
for year in df.year.unique():
#select year
df2=df[(df['year']==year)]
for col in df2.columns:
df2[col] = df2[col].astype(str)
#dictionary with date for current year
data_one_year = dict(
type='choropleth',
locations=df2['code'],
z=df2['percentage'].astype(float),
text=df2['country'],)
#add data to next year
data_slider.append(data_one_year)
#steps for the slider
steps = []
for i in range(len(data_slider)):
step=dict(method='restyle',
args=['visible',[False] * len(data_slider)],
label='year {}'.format(i+1985))
step['args'][1][i] = True
steps.append(step)
## create the sliders object from the steps
sliders = [dict(active=0, pad={"t": 1}, steps=steps)]
#layout such that there is a global view
layout = dict(title = 'Global GDP - natural earth',
geo = dict( projection = {'type':'natural earth'},
showlakes = True,
lakecolor = 'rgb(0,191,255)'))
fig = dict(data=data_slider, layout=layout)
#plot graph
plotly.offline.iplot(fig)
You can get around the value is trying to be set on a copy of a slice from a DataFrame warning, you can set the columns as strings in one step - you don't need to loop through each column name separately.
# Populate data object
for year in df.year.unique():
#select year
df2=df[(df['year']==year)]
df2.columns = df2.columns.astype(str)
#dictionary with date for current year
data_one_year = dict(
type='choropleth',
locations=df2['code'],
z=df2['percentage'].astype(float),
text=df2['country'],)
#add data to next year
data_slider.append(data_one_year)
After this change, I ran your code in Google Colab, and I am able to display the map.

Plotly - Combining Multiple Subplots with Drop Down Menu Buttons

I have monthly sales information on various companies (Amount, Profit) and would like to display all of this information in a single interactive Plotly chart - I.e. for each unique company, there should be a bar chart displaying sales amount per month as well as a line chart displaying profit per month, the two charts will share the x axis for time but have separate y axes (see example below).
This is simple enough to do for a single company using subplots, but I would like to be able to switch between companies using a dropdown menu. I have been able to get soething working, but am running into various bugs that I cannot get around.
Code to Reproduce Data:
import pandas as pd
import numpy as np
import itertools
from datetime import datetime
np.random.seed(2021)
company_list = ['Company_A', 'Company_B', 'Company_C', 'Company_D', 'Company_E']
datelist = pd.date_range(start="2020-01-01", end='2021-01-01', freq='MS').to_list()
df = pd.DataFrame(list(itertools.product(company_list, datelist)))
df.columns = ['Company', 'Date']
df['Amount'] = np.random.choice(range(0,10000), df.shape[0])
df['Profit'] = np.random.choice(range(0,10000), df.shape[0])
df.head()
I have a function which takes a data frame (assuming the same format as the one just created above) and creates a Plotly chart which has the two plots (Amount and Profit) for each company, and has a drop down menu to change from company to company.
Function to Make Multiple Plots and Dropdown Menu:
from plotly import graph_objs as go
from plotly.subplots import make_subplots
def make_multi_plot(df):
fig = make_subplots(rows=2, cols=1,
shared_xaxes=True,
vertical_spacing=0.02)
for customer in list(df.Company.unique()):
trace1 = go.Bar(
x=df.loc[df.Company.isin([customer])].Date,
y=df.loc[df.Company.isin([customer])].Amount,
name = "Amount - " + str(customer))
trace2 = go.Scatter(
x=df.loc[df.Company.isin([customer])].Date,
y=df.loc[df.Company.isin([customer])].Profit,
name = "Profit - " + str(customer)
)
fig.append_trace(trace1,1,1)
fig.append_trace(trace2,2,1)
def create_layout_button(customer):
return dict(label = customer,
method = 'restyle',
args = [{'visible': [cust == customer for cust in list(df.Company.unique())],
'title': customer,
'showlegend': True}])
fig.update_layout(
updatemenus=[go.layout.Updatemenu(
active = 0,
buttons = [create_layout_button(customer) for customer in list(df.Company.unique())]
)
])
fig.show()
At first glance, this seems to be doing what I want. However, I am running into 2 issues which I can't solve:
When the function is first called, it plots the data for ALL of the companies on the two plots, rather than just the first company (which is what I want). This does fix itself once you do select a company from the dropdown menu, although that introduces us to our next issue...
When you do select a Company from the dropdown menu, it doesn't actually update the plots correctly, it is using the wrong company's data to make the plots. If you look at the legend for the two plots, you can see that it is actually plotting the data for different companies in the set. I have no idea why this is happening and haven't been able to find any real pattern in how it's confusing the various plots with the buttons.
Appreciate any and all help!

Plotly: Follow-up How to create sunburst subplot using graph_objects?

tried the example in an earlier question but I cannot get it to "render" properly:
# imports
import pandas as pd
import plotly.graph_objects as go
import plotly.express as px
# data
df = pd.DataFrame({'BA': ['BA1', 'BA2', 'BA3', 'BA4','BA2'],
'RS': [12, 13,15, 20, 18],
'RC': ['medium','medium', 'high','high','high'] })
# plotly express figure
fig = px.sunburst(df, path=["BA", "RC"])
fig.show()
# plotly graph_objects figure
fig2=go.Figure(go.Sunburst(
labels=fig['data'][0]['labels'].tolist(),
parents=fig['data'][0]['parents'].tolist(),
)
)
fig2.show()
results in:
enter image description here
enter image description here
What am I doing wrong? (i expected it to look like the first picture).. using conda + jupyter lab
If you take a look at fig['data'], you will see that there is a field called ids which tells Plotly how to connect the parents to the labels. You need to specify this as a parameter as well.
EDIT: if you want to display values the same way as px.sunburst, you also need to include the parameter branchvalues='total'
# plotly graph_objects figure
fig2=go.Figure(go.Sunburst(
branchvalues='total',
ids=fig['data'][0]['ids'].tolist(),
labels=fig['data'][0]['labels'].tolist(),
parents=fig['data'][0]['parents'].tolist(),
values=fig['data'][0]['values'].tolist()
)
)
fig2.show()

Data not visible in plotly rangeslider

I'm using Plotly with Python and pandas df to create a gantt-chart with a rangeslider. However, the data on rangeslider is not visible and instead of appearing with the colors as in the actual plot, it appears white-colored.
Here is part of the code I'm using:
from plotly.offline import plot
import plotly.figure_factory as ff
colors = {0: 'rgb(46, 137, 205)',
1: 'rgb(58, 149, 136)',
2: 'rgb(114, 44, 121)'}
fig = ff.create_gantt(df, colors=colors, index_col='num_faces', show_colorbar=True,
bar_width=0.2, showgrid_x=True, showgrid_y=True, group_tasks=True)
fig['layout']['xaxis']['rangeselector']['visible'] = False
fig['layout']['xaxis']['rangeslider'] = dict(bgcolor='#000')
fig['layout']['xaxis']['type'] = 'date'
# yaxis customisation
fig['layout']['yaxis']['title'] = 'Number of people'
# plot customisation
fig['layout']['title'] = 'Time Spent with People'
Just for display options, I have set the background color of the rangeslider to black and here is the plot result. As you see, data is there but not colored.
Is there any solution on how to make my data visible on the rangeslider?
Thanks in advance.
I'm using plotly v.2.2.1 and Python 3.5.2.

Categories

Resources