Getting error message when add the 'Ticker' in dataframe - python

Refer to the code below:
def layout(ticker=None, **other_unknown_query_strings):
# get data for stock ticker from yahoo finance
df = yf.Ticker(ticker).history(period="12mo").reset_index()
df["Date"] = pd.to_datetime(df["Date"])
How about can I apply the same in the dataframe if I change the data location which is come from the excel csv instead of yahoo finance.
I had tried but will getting an error message
AttributeError: 'DataFrame' object has no attribute 'Ticker'
code I tried:
def layout(ticker= None, **other_unknown_query_strings):
dff = pd.read_csv("dummy2.csv")
df = dfk.Ticker(ticker).reset_index()
Expected output:
When user click the 'Microsoft', the another page will display the 'Microsoft' information in graph and table format.
Referring to multi_page_table_links
page1.py
from dash import dash_table, dcc, html, register_page
import pandas as pd
import dash_bootstrap_components as dbc
register_page(__name__, path="/")
# Create dataframe
equities = {
"Apple": "AAPL",
"Microsoft": "MSFT",
"Amazon": "AMZN",
"Alphabet": "GOOGL",
"Berkshire Hathaway": "BRK.B",
"Johnson & Johnson": "JNJ",
}
data = {
"Equities": [f"[{stock}](/stocks/{ticker})" for stock, ticker in equities.items()],
"Quantity": [75, 40, 100, 5, 40, 60],
"Market Price": [131.55, 247.39, 105.80, 2143.50, 268.08, 169.85],
"Market Value": [9866.25, 9895.60, 10580.00, 10717.50, 10723.2, 10191.00],
}
df = pd.DataFrame(data)
# dash.DataTable with links formatted by setting the column to "presentation": "markdown"
datatable = dash_table.DataTable(
data=df.to_dict("records"),
columns=[{"id": "Equities", "name": "Equities", "presentation": "markdown"}]
+ [{"id": c, "name": c} for c in df.columns if c != "Equities"],
markdown_options={"link_target": "_self"},
css=[{"selector": "p", "rule": "margin: 0"}],
style_cell={"textAlign": "right"},
)
# html table with links formatted using dcc.Link()
df["Equities"] = [
dcc.Link(f"{stock}", href=f"/stocks/{ticker}") for stock, ticker in equities.items()
]
table = dbc.Table.from_dataframe(df, striped=True, bordered=True, hover=True)
layout = html.Div(
[
html.H5(
"html table with dcc.Link Note: No page refresh on navigation",
className="mt-5",
),
table,
html.H5(
"DataTable with Markdown links", className="mt-5"
),
datatable,
]
)
page2.py
import dash
from dash import Dash, dash_table, html, dcc, Input, Output
import plotly.graph_objects as go
import yfinance as yf
import pandas as pd
def title(ticker=None):
return f"{ticker} Analysis"
def description(ticker=None):
return f"News, financials and technical analysis for {ticker}"
dash.register_page(
__name__,
path_template="/stocks/<ticker>",
title=title,
description=description,
path="/stocks/aapl",
)
def layout(ticker=None, **other_unknown_query_strings):
# get data for stock ticker from yahoo finance
df = yf.Ticker(ticker).history(period="12mo").reset_index()
df["Date"] = pd.to_datetime(df["Date"])
if df.empty:
return html.H3("No data available")
table = dash_table.DataTable(
data=df.to_dict("records"),
columns=[{"name": i, "id": i} for i in df.columns],
sort_action="native",
style_table={"overflowX": "auto"},
page_size=10
)
# create a figure based on the ticker
fig = go.Figure(
go.Candlestick(
x=df["Date"],
open=df["Open"],
high=df["High"],
low=df["Low"],
close=df["Close"],
)
)
# stock page layout
return html.Div(
[
html.H3(f"Market prices last 12 months for: {ticker}"),
dcc.Graph(figure=fig),
table,
]
)

Related

Filtering a column on Dash dataTable based on a list

I am very new to Dash. I have made a dataTable that includes several columns. These columns can be filtered and sorted. However, one problem with the filtering is that I cannot filter based on a list (like pandas .loc) e.g. if I want to filter the countries based on a list (say, ['India', 'United States']), the filter does not work. I have previously checked the advanced filtering here and found that I can use || operators; however,this would not be a good choice if the list is more than 4 or 5.
Here's the code:
import dash
from dash.dependencies import Input, Output
import dash_table
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import json
df = pd.read_csv(
'https://raw.githubusercontent.com/plotly/datasets/master/gapminder2007.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
html.Div(id='heading-users', children='Users\' Country details', style={
'textAlign': 'center', 'font-family': 'Helvetica'}),
dash_table.DataTable( # users
id='datatable-users',
columns=[
{"name": i, "id": i, "deletable": True, "selectable": True} for i in df.columns
],
data=df.to_dict('records'),
editable=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
row_selectable="multi",
row_deletable=True,
selected_columns=[],
selected_rows=[],
page_action="native",
page_current=0,
page_size=20,
export_format='csv'
),
html.Div(id='datatable-users-container')
])
#app.callback(
Output('datatable-users-container', "children"),
Input('datatable-users', "derived_virtual_data"),
Input('datatable-users', "derived_virtual_selected_rows"))
def update_graphs(rows, derived_virtual_selected_rows):
if derived_virtual_selected_rows is None:
derived_virtual_selected_rows = []
dff = df if rows is None else pd.DataFrame(rows)
colors = ['#7FDBFF' if i in derived_virtual_selected_rows else '#0074D9'
for i in range(len(dff))]
return [
dcc.Graph(
id=column,
figure={
"data": [
{
"x": dff["country"],
"y": dff[column],
"type": "bar",
"marker": {"color": colors},
}
],
"layout": {
"xaxis": {"automargin": True},
"yaxis": {
"automargin": True,
"title": {"text": column}
},
"height": 250,
"margin": {"t": 10, "l": 10, "r": 10},
},
},
)
# check if column exists - user may have deleted it
# If `column.deletable=False`, then you don't
# need to do this check.
for column in ["pop", "lifeExp", "gdpPercap"] if column in dff
]
if __name__ == '__main__':
app.run_server(debug=True)
From that link - The 'native' filter function doesn't support 'OR' operations within a single column. Assign filter_action="custom" then create a callback to update the table children. See the 'Back-End Filtering section of that link.
You'll need to grab the filter query string in a callback and decompose to extract the column name and query string. With that you can query the pandas dataframe and return the results in a callback. I don't have the code for "OR" functionality but found some I used that can query pandas once you have the input values
def filter_df(df, filter_column, value_list):
conditions = []
for val in value_list:
conditions.append(f'{filter_column} == "{val}"')
query = ' or '.join(conditions)
print(f'querying with: {query}')
return df.query(query_expr)
filter_df(df, 'country', ['Albania', 'Algeria'])

Plotly Dash: go.Choropleth subunitwidth not working

Can somebody give me a hint of why this part of my go.Choropleth code is not working?
I'm trying to make my country's borders a little more thicker and black, but it's not working and I don't know what else I could be missing on this layout specs... Here is my map code section and below it you can check a zoomed part of the map generated. Notice the country's borders are still thin and grey, why it does not change?
map_fig_layout = {'coloraxis_colorbar': {'title': 'População (%)',
'thickness': 20,
'ticklabelposition':'outside bottom'},
'margin': {'r':0, 'l':0, 't':0, 'b':0},
'template': 'plotly_dark',
'geo':{'projection': go.layout.geo.Projection(type ='natural earth'),
'landcolor': '#262626',
'showcountries':True,
'showsubunits':True,
'subunitcolor': 'black',
'subunitwidth': 4,
'resolution':110,
'visible':True,
'countrywidth': 4,
'countrycolor' : 'black'},
'uirevision':'not_tracked_key'}
map_graph = go.Figure({'data':[ go.Choropleth(locations = dff['Code'],
z = dff['população_%'], # a column of dff
hovertext = dff['Entity'],
zmin = 0,
zmax = 100,
colorscale = make_colorscale( ['#F53347','#E6C730','#2FF5A8'] ),
geo = 'geo') ],
'layout': map_fig_layout})
Try adding this line to your code:
fig.update_traces(marker_line_width=2.0, selector=dict(type='choropleth'))
or in your case:
map_graph.update_traces(marker_line_width=2.0, selector=dict(type='choropleth'))
You can additionally control the opacity, if so desired:
E.g.,
from urllib.request import urlopen
import json
with urlopen('https://raw.githubusercontent.com/plotly/datasets/master/geojson-counties-fips.json') as response:
counties = json.load(response)
import pandas as pd
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/fips-unemp-16.csv",
dtype={"fips": str})
import plotly.express as px
fig = px.choropleth(df, geojson=counties, locations='fips', color='unemp',
color_continuous_scale="Viridis",
range_color=(0, 12),
scope="usa",
labels={'unemp':'unemployment rate'}
)
fig.update_layout(margin={"r":0,"t":0,"l":0,"b":0})
fig.update_traces(marker_line_width=3.0, marker_opacity=0.6, selector=dict(type='choropleth'))
fig.show()
Docs References
https://plotly.com/python/reference/choropleth/#choropleth-marker
using your code (make sure you format it to be PEP8 compliant for future questions)
sourced some data from kaggle to make this a re-producible example
examples of subunits are counties / regions in a country
import kaggle.cli
import sys, requests
import pandas as pd
from pathlib import Path
from zipfile import ZipFile
import urllib
import plotly.graph_objects as go
from plotly.colors import make_colorscale
# fmt: off
# download data set
url = "https://www.kaggle.com/mohaiminul101/population-growth-annual"
sys.argv = [sys.argv[0]] + f"datasets download {urllib.parse.urlparse(url).path[1:]}".split(" ")
kaggle.cli.main()
zfile = ZipFile(f'{urllib.parse.urlparse(url).path.split("/")[-1]}.zip')
dfs = {f.filename: pd.read_csv(zfile.open(f)) for f in zfile.infolist()}
# fmt: on
dff = dfs["world_population_growth.csv"].rename(
columns={"Country Code": "Code", "2019": "população_%", "Country Name": "Entity"}
)
dff["população_%"] = dff["população_%"] * 100
map_fig_layout = {
"coloraxis_colorbar": {
"title": "População (%)",
"thickness": 20,
"ticklabelposition": "outside bottom",
},
"margin": {"r": 0, "l": 0, "t": 0, "b": 0},
"template": "plotly_dark",
"geo": {
"projection": go.layout.geo.Projection(type="natural earth"),
"resolution": 110,
"visible": True,
},
"uirevision": "not_tracked_key",
}
map_graph = go.Figure(
{
"data": [
go.Choropleth(
locations=dff["Code"],
z=dff["população_%"], # a column of dff
hovertext=dff["Entity"],
zmin=0,
zmax=100,
marker={"line":{"width":4, "color":"black"}},
colorscale=make_colorscale(["#F53347", "#E6C730", "#2FF5A8"]),
)
],
"layout": map_fig_layout,
}
)
map_graph

Insert shape in Dash DataTable

I have the below datatable in dash. Code for generating this table is below:
import dash
import dash_table
import pandas as pd
data = {'value':['very low','low','medium','high','very high'],'data':[1,3,5,7,10]}
df = pd.DataFrame(data)
app = dash.Dash(__name__)
app.layout = dash_table.DataTable(
id='table',
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict('records'),
)
if __name__ == '__main__':
app.run_server(debug=True)
But I want to generate the below table. How can i do this using dash? The indicator column is a shape that is color coded based on a scale (For eg. 5 is medium and hence yellow/amber, above 5 the value go from green to dark green. Similarly, values below 5 go from amber to red
Thanks to Eduardo on the plotly community forum I learned that we can now use html content for Markdown cells of a DataTable (plotly forum thread, github pull request).
This allows us to do something like this:
import dash
import dash_html_components as html
import dash_table
import pandas as pd
def get_svg_arrow(val):
if val > 7:
fill = "green"
elif val > 5:
fill = "blue"
elif val == 5:
fill = "yellow"
elif val >= 3:
fill = "orange"
else:
fill = "red"
if val >= 5:
path = f'<path d="M19.5 11L26 11L13 -1.1365e-06L7.97623e-09 11L6.5 11L6.5 22L19.5 22L19.5 11Z" fill="{fill}"/>'
else:
path = (
f'<path d="M6.5 11H0L13 22L26 11L19.5 11V0L6.5 0L6.5 11Z" fill="{fill}"/>'
)
return f'<svg width="26" height="22" viewBox="0 0 26 22" fill="none" xmlns="http://www.w3.org/2000/svg">{path}</svg>'
values = [1, 3, 5, 7, 10]
data = {
"value": ["very low", "low", "medium", "high", "very high"],
"indicator": [get_svg_arrow(val) for val in values],
"data": values,
}
df = pd.DataFrame(data)
app = dash.Dash(__name__)
app.layout = html.Div(
[
dash_table.DataTable(
css=[dict(selector="p", rule="margin: 0px; text-align: center")],
data=df.to_dict("records"),
style_cell={"textAlign": "center"},
columns=[
{"name": col, "id": col, "presentation": "markdown"}
if col == "indicator"
else {"name": col, "id": col}
for col in df.columns
],
markdown_options={"html": True},
)
]
)
if __name__ == "__main__":
app.run_server()
So the idea of the code above is to dynamically create an arrow svg with a fill color based on the data.
For creating the svg arrows I've used a vector drawing program and exported to svg, but you could construct the path manually if you wanted to.
Result

Export Plotly Dash datatable output to a CSV by clicking download link

Hi Anyone able to help advise?
I have an issue trying to export the data being populated from data table filtered from drop down selection upon clicking on download link to a CSV file.
Error gotten after clicking on the Download Link
csv_string = dff.to_csv(index=False, encoding='utf-8')
AttributeError: 'str' object has no attribute 'to_csv'
And the file that was downloaded is a file containing html code.
Code snippets below
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output,State
import plotly.graph_objs as go
import dash_table
import dash_table_experiments as dt
from urllib.parse import quote
import flask
import pandas as pd
import numpy as np
import pyodbc
app.layout = html.Div([
html.H3("Sales Summary Report"),
dcc.Graph(
figure={
"data": [
{
"x": df["Sales_RANGE"],
"y": df['count'],
"name":'No of Cust',
"type": "bar",
"marker":{'color':'rgba(26, 118, 255, 0.5)',
#'line':{
# 'color':'rgb(8,48,107)',
# 'width':1.5,
# }
}
}
],
"layout": {
"xaxis": {"automargin": True},
"yaxis": {
"automargin": True,
# "title": {"text": column}
},
"height": 250,
"margin": {"t": 10, "l": 10, "r": 10},
},
},
)
,
html.Label(["Select Sales range to view",
dcc.Dropdown(
id="SalesRange",
style={'height': '30px', 'width': '55%'},
options=[{'label': i,
'value': i
} for i in Sales_Range_Options],
value='All'
)
]),
#TABLE
html.H5("Details"),
html.Div(id='detailsresults') ,
html.A('Download Data',
id='download-link',
download="rawdata.csv",
href="",
target="_blank"
)
])
def generate_table(dataframe):
'''Given dataframe, return template generated using Dash components
'''
return html.Div( [dash_table.DataTable(
#id='match-results',
data=dataframe.to_dict('records'),
columns=[{"name": i, "id": i} for i in dataframe.columns],
editable=False
),
html.Hr()
])
#app.callback(
Output('detailsresults', 'children'),
[
Input('SalesRange', 'value'),
]
)
def load_results(SalesRange):
if SalesRange== 'All':
return generate_table(df)
else:
results = df[df['SALES_RANGE'] == SalesRange]
return generate_table(results)
#app.callback(
dash.dependencies.Output('download-link', 'href'),
[dash.dependencies.Input('SalesRange', 'value')])
def update_download_link(SalesRange):
dff = load_results(SalesRange)
csv_string = dff.to_csv(index=False, encoding='utf-8')
csv_string = "data:text/csv;charset=utf-8,%EF%BB%BF" + quote(csv_string)
return csv_string
CSV export is officially supported by dash_table.DataTable. You simply need to specify export_format='csv' when you build the table:
dash_table.DataTable(
id="table",
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict("records"),
export_format="csv",
)
Here's a complete example app.py that you can run:
import dash
import dash_table
import dash_html_components as html
import pandas as pd
df = pd.DataFrame(
[
["California", 289, 4395, 15.3, 10826],
["Arizona", 48, 1078, 22.5, 2550],
["Nevada", 11, 238, 21.6, 557],
["New Mexico", 33, 261, 7.9, 590],
["Colorado", 20, 118, 5.9, 235],
],
columns=["State", "# Solar Plants", "MW", "Mean MW/Plant", "GWh"],
)
app = dash.Dash(__name__)
server = app.server
app.layout = dash_table.DataTable(
id="table",
columns=[{"name": i, "id": i} for i in df.columns],
data=df.to_dict("records"),
export_format="csv",
)
if __name__ == "__main__":
app.run_server(debug=True)
You will see a button above the table:
I believe your answer is like the following:
#app.server.route('/dash/urlToDownload')
def download_csv():
return send_file('output/downloadFile.csv',
mimetype='text/csv',
attachment_filename='downloadFile.csv',
as_attachment=True)
You may take a look at this link for more information:
Allowing users to download CSV on click

How do I return a dataframe from an app.callback with my as output as dbc.Table.from_dataframe

I am trying to have a table load upon clicking a search button, and provide ID/password. My output is a dbc.Table.from_dataframe which allows an df argument; however when I use this as my output property, I am getting an error.
Here are the available properties in "my_table":
['children', 'id', 'style', 'className', 'key', 'tag', 'size', 'bordered', 'borderless', 'striped', 'dark', 'hover', 'responsive', 'loading_state']
I read the docs here
https://dash-bootstrap-components.opensource.faculty.ai/l/components/table
I tried such using 'children' and that didn't work either. I know with dcc table I need to return a dictionary, however I thought with dbc.Table.from_dataframe I can return a dataframe.
#app.callback(Output('my_table', 'df' ),
[Input('search-button','n_clicks')],
[State('input-id', 'value'),
State('input-password', 'value')]
)
def search_fi(n_clicks, iuser, ipasw):
if n_clicks > 0:
df = pd.DataFrame(
{
"First Name": ["Arthur", "Ford", "Zaphod", "Trillian"],
"Last Name": ["Dent", "Prefect", "Beeblebrox", "Astra"],
}
return df
import dash
import dash_html_components as html
import dash_bootstrap_components as dbc
import pandas as pd
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
html.Button('Table', id='table-but', n_clicks=0),
html.Div(id='container-button-basic')
])
#app.callback(
dash.dependencies.Output('container-button-basic', 'children'),
[dash.dependencies.Input('table-but', 'n_clicks')])
def search_fi(n_clicks):
if n_clicks > 0:
df = pd.DataFrame(
{
"First Name": ["Arthur", "Ford", "Zaphod", "Trillian"],
"Last Name": ["Dent", "Prefect", "Beeblebrox", "Astra"]
})
print(df)
return dbc.Table.from_dataframe(df)
if __name__ == '__main__':
app.run_server(debug=True)
or
https://plotly.com/python/table/ figure
Html dash table html-table
Example

Categories