How to graph data from a CSV file using Dash, Plotly - python

I am new to python and am looking for ways in which I can visualise data. I have come across 'Dash' - but wondered how I would show a graph based on data that is saved in a CSV?
Currently I have this.. But it only shows a blank graph.
Any help would be welcomed - thanks in advance.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
df = pd.read_csv('d6.csv')
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(id="graph"),
html.Button("Switch Axis", id='btn', n_clicks=0)
])
#app.callback(
Output("graph", "figure"),
[Input("btn", "n_clicks")])
def display_graph(n_clicks):
if n_clicks % 2 == 0:
x, y = 'Time', 'R1Temp'
else:
x, y = 'R1Temp', 'Time'
fig = px.line(df, x=x, y=y)
return fig
app.run_server(debug=False)

Pandas is your friend, it gives you access to a data structure called a dataframe. I highly recommend you look through some tutorials on pandas as they come up everywhere in the data science field. In addition plotly often looks for dataframes as inputs into their API.
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.html
But to cut to the chase, a dataframe can load a CSV with 100% structure retention
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html#pandas.read_csv
https://datatofish.com/export-dataframe-to-csv/
Once you load the csv to a dataframe you can access rows and columns with queries.
https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.columns.html

Related

Visualize a 408x408 numpy array as a heatmap

Hello I want to visualize the sandbox game map. I have collected the data from API and now I want to create a heatmap kind of visualization, where the color changes depending on how many times the land's been sold. I'm looking for a Python tool / GUI that will let me visualize a 408x408 numpy array. I've tried the seaborn heatmap, but it doesn't look clean (see image), even If I try to set figsize to (200, 200) it's not big enough for my needs. I want to have a visualization on potentially whole screen, where each land is big enough so that I can write something on it (potentially price). Better option would be to have a big map with sliders.
Perhaps it's possible to do what I want using Seaborn's heatmap, but I'm not very familiar with it.
Here's the code I used for visualization:
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np
arr = np.random.rand(408, 408)
x_labels = list(range(-204, 204))
y_labels = list(reversed(range(-204, 204)))
fig, ax = plt.subplots(figsize=(100, 100))
sns.heatmap(arr, square=True, xticklabels=x_labels, yticklabels=y_labels, ax=ax)
ax.tick_params(axis="both", labelsize=40)
Visualizing such large data with seaborn or Matplotlib will be difficult.
For that, we can use Plotly and the dash python library. So, we can add a slider to view some portion of data at a time.
I have used these two libraries.
import plotly.express as px
from dash import Dash, dcc, html, Input, Output
import numpy as np
import pandas as pd
#creating data
arr = np.random.rand(408, 408)
x_labels = list(range(-204, 204))
y_labels = list(reversed(range(-204, 204)))
#Converted to dataframe
df_data = pd.DataFrame(arr,index =y_labels, columns = [x_labels] )
app = Dash(__name__)
#How many items to show at a time
show_item_limit = 20
app.layout = html.Div([
html.H4('Range'),
dcc.Graph(id="graph"),
html.P("Select range"),
dcc.Slider(
min = 0,
max = 408-show_item_limit,
step = show_item_limit,
value = 0,
id= 'my-slider'
),
])
#app.callback(
Output("graph", "figure"),
Input("my-slider", "value"))
def filter_heatmap(selected_value):
# Selected value will be passed from Slider
df = df_data # replace with your own data source
#We can filter the data here
filtered_df = df_data.iloc[selected_value:selected_value+show_item_limit,range(selected_value,selected_value+show_item_limit)]
#Update using plotly
fig = px.imshow(filtered_df,
text_auto=True,
labels=dict(x="X-range", y="y-range"),
x = filtered_df.columns,
y = filtered_df.index
)
return fig
app.run_server(debug=True)
See the output image: Output from code

Fixing x_range in plotly express histogram messes up x axis in rug plot

I am creating a histogram using plotly express, and I want to use the argument marginal='rug'. When trying to disable zooming on the x axis by using histogram.update_xaxes(fixedrange=True), this messes up the x range in the rugplot.
Here are the two outputs, one with fixedrange=False and one with fixedrange=True. Note how the points above the bars are off in the second plot.
I would really like to disable the zooming, but have the x axes match between the bars and the points. How do I do this?
For reproducibility, here's the code for this minimal example, you can just copy and run it.
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import plotly.express as px
import pandas as pd
import dash_daq as daq
app = dash.Dash(__name__)
app.layout = html.Div([
dcc.Graph(id="graph"),
html.Label("Make x axis zoomable"),
daq.ToggleSwitch(
id='x_toggle_switch',
value=False
)
])
#app.callback(
Output("graph", "figure"),
[Input('x_toggle_switch', 'value')])
def make_x_zoomable(x_zoomable):
start, end = 0, 25
df = pd.DataFrame({'x': [0, 5, 10, 15, 20, 25]})
histogram = px.histogram(df, x='x',
nbins=end - start + 1,
range_x=[start, end],
marginal='rug',
barmode='overlay',
template='plotly_white')
histogram.update_layout(showlegend=False, yaxis_title='y', xaxis_title='x')
# disable zooming
histogram.update_xaxes(fixedrange=x_zoomable)
histogram.update_yaxes(fixedrange=True)
return histogram
app.run_server(debug=True)

Remove responsive feature with Dash plotly

I'm on google colab with MacOS 11.5.2.
Dash version I'm using is 1.21.0
I'm usually write dash code in bigger screen, and now I'm notice this issue when move to smaller screen. Here's a the example :
import plotly.express as px
from jupyter_dash import JupyterDash
import dash_bootstrap_components as dbc
import dash_core_components as dcc
import dash_html_components as html
app = JupyterDash(__name__,external_stylesheets=[dbc.themes.BOOTSTRAP])
app.layout = html.Div([
dbc.Row([dbc.Col("Top left"),dbc.Col("Top right")]),
dbc.Row([dbc.Col("Bottom left"),dbc.Col("Bottom right")])
]
)
if __name__ == "__main__":
app.run_server()
And the output is as expected, 2 x 2 grid with each word in respective position.
But when I'm replacing the text with plot, the grid structure changed automatically.
app = JupyterDash(__name__,external_stylesheets=[dbc.themes.BOOTSTRAP])
df = px.data.tips()
fig1 = px.histogram(df,x="tip")
fig2 = px.scatter(df,x="total_bill",y="tip")
fig3 = px.bar(df,x="sex")
fig4 = px.histogram(df,x="total_bill")
app.layout = html.Div([
dbc.Row([dbc.Col(dcc.Graph(figure=fig1,id="Histogram tip")),dbc.Col(dcc.Graph(figure=fig2,id="Scatter plot bill vs tip"))]),
dbc.Row([dbc.Col(dcc.Graph(figure=fig3,id="Barplot gender "),width=3),dbc.Col(dcc.Graph(figure=fig4,id="Histogram bill"),width=9)])
]
)
if __name__ == "__main__":
app.run_server()
Now the first row become stacked vertically instead of horizontally stacked. Here's the screenshot (I zoom out a bit)
But if i really zoom out my browser that far, the displayed layout is correctly appear
I don't understand why the responsive layout feature kicks in this scenario and I want to turn it off so my dashboard appear in 2x2 instead of 3 rows layout.
I finally solve it by using dbc.Container to my app and set fluid=False.

auto ranging y axis in plotly python

I want to plot a graph in plotly. while set the range to zoom with rangelider, the y axis is fixed and make data in flat. I found a page that one expert guy did it, but I can not do it
Is there any one that can make it happen
https://community.plotly.com/t/y-axis-autoscaling-with-x-range-sliders/10245/11
at this page the second graph is a animation gif this is what exactly I have to do
This is the same technique but using dash to capture event and trigger callback. Additional reference: graph slider as input
from jupyter_dash import JupyterDash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output, State
import plotly.express as px
import numpy as np
import pandas as pd
# generate some data and a figure...
s = 500
df = pd.DataFrame({"date": pd.date_range("1-jan-2020", periods=s), "val": np.random.uniform(0, 1, s)})
df = df.assign(val=df["val"] * (df["date"] - df["date"].min()).dt.days ** 3)
fig = px.line(df, x="date", y="val")
fig = fig.update_layout(xaxis={"rangeslider": {"visible": True}, "range":[df["date"].quantile(.75), df["date"].max()]})
# Build App
app = JupyterDash(__name__)
app.layout = html.Div([
dcc.Graph(id='dashFig', figure=fig),
], style={"font-family": "Arial", "font-size":"0.9em"})
# get callback from rangeslider and update ranges on x & y axis
#app.callback(Output('dashFig', 'figure'),
[Input('dashFig', 'relayoutData')])
def rangesliderchg(relayoutData):
if relayoutData and "xaxis.range" in relayoutData.keys():
s = df.loc[df["date"].between(relayoutData['xaxis.range'][0], relayoutData['xaxis.range'][1]), "val"]
fig["layout"]["yaxis"]["range"] = [s.min(), s.max()]
fig["layout"]["xaxis"]["range"] = relayoutData['xaxis.range']
return fig
# Run app and display result inline in the notebook
app.run_server(mode='inline')

Is there a way to alter interday stock graphs on dash with python so that times after 16:00 and before 9:30 are not plotted?

I want to create a dashboard that shows inter-day price movement of stocks on dash in python but times after the market closes are being shown even though there is no data in between those times.
Is there a way to amend the graph to pick up at 09:30 from where it left off at 16:00?
I have tried to graph as objects:
import pandas as pd
import quandl
import fix_yahoo_finance as yf
import numpy as np
from datetime import datetime, date, time, timedelta
import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly as plt
from plotly import graph_objs as go
from dash.dependencies import Input, Output
from pandas import ExcelWriter
from openpyxl import Workbook
dayDates = []
endt = datetime.today()
dayDates.append(endt.strftime('%Y-%m-%d'))
begdt = endt + timedelta(days=-3)
dayDates.append(begdt.strftime('%Y-%m-%d %H:%M:%S'))
trbegdt = endt + timedelta(days=-365)
dayDates.append(trbegdt.strftime('%Y-%m-%d'))
# Pulls minute by minute stock prices from short term variable to today
yfdfmin = yf.download("^DJI", start=begdt, end=endt, interval="1m")['Adj Close']
yfdfmin.index = yfdfmin.index.strftime('%Y-%m-%d %H:%M:%S')
app = dash.Dash()
colors = {
'background': '#fcfcfc',
'text': '#353844'
}
app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
dcc.Graph(
id='Dow',
figure={
'data': [
go.Scatter(x=list(yfdfmin.index),
y=list(yfdfmin['^DJI']),
# visible=False,
name="Close",
showlegend=False)
]
}
),
])
if __name__ == '__main__':
app.run_server(debug=True)
Here is the result:
I found a solution to my own problem that in retrospect is quite simple. I simply deleted the x-axis from my graph so that only the values were plotted. Hope this simple solution can help others.

Categories