I am using plotly(python) to implement range selector where I've created multiple buttons for selecting ranges and I want to show only one month data by default but it showing all data. My code and its output are below what changes should I make?
import plotly.graph_objects as go
import pandas as pd
# Load data
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv")
df.columns = [col.replace("AAPL.", "") for col in df.columns]
# Create figure
fig = go.Figure()
fig.add_trace(
go.Scatter(x=list(df.Date), y=list(df.High)))
# Set title
fig.update_layout(
title_text="Time series with range slider and selectors"
)
# Add range slider
fig.update_layout(
xaxis=dict(
rangeselector=dict(
buttons=list([
dict(count=1,
label="1m",
step="month",
stepmode="backward"),
dict(count=6,
label="6m",
step="month",
stepmode="backward"),
dict(count=1,
label="YTD",
step="year",
stepmode="todate"),
dict(count=1,
label="1y",
step="year",
stepmode="backward"),
dict(step="all")
])
),
rangeslider=dict(
visible=True
),
type="date"
)
)
fig.show()
You can add range=[{start_date},{end_date}] to the dictionary you're passing to the xaxis parameter. For example:
fig.update_layout(
xaxis=dict(
rangeselector=dict(
buttons=list([
dict(count=1,
label="1m",
step="month",
stepmode="backward"),
dict(count=6,
label="6m",
step="month",
stepmode="backward"),
dict(count=1,
label="YTD",
step="year",
stepmode="todate"),
dict(count=1,
label="1y",
step="year",
stepmode="backward"),
dict(step="all")
])
),
rangeslider=dict(
visible=True
),
type="date",
range=["2016-01-01","2016-02-01"]
)
)
Related
I have this plot-
fig = go.Figure()
fig.add_trace(
go.Scattergl(x=list(df.Date), y=list(df.Measure)), row = 1, col = 1)
fig.update_layout(
xaxis=dict(
rangeselector=dict(
buttons=list([
dict(count=1,
label="1m",
step="month",
stepmode="backward"),
dict(count=6,
label="6m",
step="month",
stepmode="backward")
])
),
rangeslider=dict(
visible=True
),
type="date"
)
)
I want to set it up so that when someone opens the dashboard, they 6 month range selector is already clicked. The underlying data goes back further than six months, and I want the dashboard to auto-select the six month option when the dashboard starts. Is that possible with range selector?
I tried changing background color of menu button in plotly, code is running sucessfully but "bgcolor:grey" changes are not applied.
I checked documentation and used same syntax,code is running.
Code-
df['vix'] = nf_vix['Close'].round(decimals = 1)
fig = go.Figure(
data=[ go.Scatter(x=df.index,y=df.vix, line=dict(color='green', width=3),name='Low Volatility',fill='tozeroy'),
go.Scatter(x=df.index,y=df.vix.where(df.vix >= 20), mode='lines+markers',line=dict(color='red', width=3),name='High Volatality',fill='toself')],
layout_title_text="NIFTY Volatality Index" )
#Hide Weekends and Added Range Slider
fig.update_xaxes( rangeslider_visible=True, rangebreaks=[ dict(bounds=["sat", "mon"])])
fig.update_layout( xaxis_tickformat = ' %d %B (%a)<br> %Y',xaxis_title='Date',yaxis_title='Range',template ='plotly_dark',legend = dict(bgcolor = 'rgba(0,0,0,0)'))
##https://plotly.com/python/legend/
fig.update_layout(legend=dict(
orientation="h",
yanchor="bottom",
y=1.02,
xanchor="right",
x=1
))
# fig.add_hrect(y0=0, y1=20,
# annotation_text="Low volatality", annotation_position="top left",
# fillcolor="green", opacity=0.25, line_width=0)
fig.update_layout(
xaxis=dict(rangeselector=dict(buttons=list([
dict(count=1,label="1m",step="month",stepmode="backward"),dict(count=3,label="3m",step="month",stepmode="backward"),
dict(count=6,label="6m",step="month",stepmode="backward"),
dict(count=1,label="YTD",step="year",stepmode="todate"),
dict(step="all") ]) ),rangeslider=dict(visible=False),type="date"))
# fig.update_layout(updatemenus=dict(bgcolor = 'grey'))
fig.update_layout({
'updatemenus': [{'bgcolor' : 'grey'}]})
fig.show()
doc- https://plotly.com/python/reference/layout/updatemenus/
Viz Snap -
Update--
Now I have added the below code in above code, the font color changed to "black". I want to know if "background color" of "range selector" buttons can be changed or not.
I got github link but this attribute rangeselector.activebgcolor is not working.
Link - https://github.com/plotly/plotly.js/issues/790
fig.update_layout(xaxis=dict(rangeselector = dict(font = dict( color = "black"))))
Updated Snap-
Update: The font color and background color of the range selector button and the background color of the active button can be changed with The answer is taken from the official reference.
import plotly.express as px
import pandas as pd
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv')
fig = px.line(df, x='Date', y='AAPL.High', title='Time Series with Range Slider and Selectors')
fig.update_xaxes(
rangeslider_visible=True,
rangeselector=dict(
buttons=list([
dict(count=1, label="1m", step="month", stepmode="backward"),
dict(count=6, label="6m", step="month", stepmode="backward"),
dict(count=1, label="YTD", step="year", stepmode="todate"),
dict(count=1, label="1y", step="year", stepmode="backward"),
dict(step="all")
])
)
)
# update
fig.update_layout(template='plotly_dark',
xaxis_rangeselector_font_color='black',
xaxis_rangeselector_activecolor='red',
xaxis_rangeselector_bgcolor='green',
)
fig.show()
I'm working on a Dash App that represents graphs about data in a database. One column of the database is a list of journals and I represented this column in a pie and in a bar chart with the respective frequency of each journal. I decided to put also a CheckList, because the database can change and if there are too many journals, the graphs are no more readable. So at the beginning only the first 15 items of the list are shown in the graphs, like the image below.
The problem is that, if I change the selected journals in the Checklist, the graphs update correctly but the width of the bar chart decreases and I don't understand why. In the image below it is possible to see that, changing the selection, the graph dimension is reduced and re-checking the two items, the graph does not return with the initial dimension anymore. Why?
(The graphs are created in a callback after the selection of the database in a dropdown)
#app.callback(
Output('first_graph', 'children'),
Input('database', 'value')
)
def create_graph(value):
if value is not None: #if i select the database from a dropdown, the graphs appear
df = pd.read_csv(value)
#Count unique values: index takes the values, the other takes the counts
journals = df['Journal'].value_counts().index.tolist() # --> x
journals_frequency = df['Journal'].value_counts().tolist() # --> y
trace1 = go.Bar(y=journals, x=journals_frequency,orientation='h', name='Number of journals',
marker=dict(color=color_charts_journals)) #'h' stays for horizontal
layout1 = go.Layout(autosize=False,
width=450,
height=350,
xaxis=dict(tickformat=',d', showgrid=False),
yaxis=dict(type='category', tickmode='linear', showticklabels=False, showgrid=False),
margin=dict(t=25,b=25,l=5,r=5),
bargap=0,
)
fig1=go.Figure(data=[trace1],layout=layout1)
pie_journals = go.Pie(labels=journals, values=journals_frequency, hole=0.5, showlegend=False,textposition='inside',
name='Frequency of Journals',marker=dict(colors=color_charts_journals))
fig_pie_journals = go.Figure(data=[pie_journals])
fig_pie_journals.update_layout(title={
'text': "Frequency of journals",
'y':1,
'x':0.5,
'xanchor': 'center',
'yanchor': 'top'},
autosize=False,
width=450,
height=350,
margin=dict(t=20, b=15, l=5, r=5),)
return html.B('List of journals', style={'textAlign': 'center','width': '50%'}),
html.Div([
dcc.Checklist(
id="all-or-none",
options=[{"label": "Select All", "value": "All"}],
value=[],
)]),
html.Div([
dcc.Checklist(
id='checklist_journals',
options=[
{'label': x, 'value': x, 'disabled': False}
for x in sorted(journals) #set in alphabetical order
],
value=sorted(journals)[0:15],
labelStyle={'display': 'block','margin-left':'40px','margin-top':'10px'}
)],style={'width': '33%', 'display': 'inline-block',"overflow-y":"scroll","height": "350px"}), #'backgroundColor':'blue'
html.Div([dcc.Graph(id='journals_pie',figure=fig_pie_journals)],style={'width': '33%', 'display': 'inline-block'}),
html.Div([dcc.Graph(id='journals_graph', figure=fig1)],style={'width': '33%', 'display': 'inline-block'}),
#callback for select all values of the checklist
#app.callback(
Output("checklist_journals", "value"),
[Input("all-or-none", "value")],
[State("checklist_journals", "options"),State("checklist_journals", "value")],
)
def select_all_none(all_selected, options, values_checklist):
if all_selected: #se clicco seleziona tutto
all_or_none = []
all_or_none = [option["value"] for option in options if all_selected]
return all_or_none
else:
return values_checklist[0:15] #se non clicco seleziona i primi 15 altrimenti si tolgono tutti
#callback to choose values in pie journals and bar journals
#app.callback(
[Output(component_id='journals_pie', component_property='figure'),Output('journals_graph','figure')],
[Input('database', 'value'),Input(component_id='checklist_journals', component_property='value')]
)
def update_graph(value,options_chosen):
if value is not None:
df = pd.read_csv(value)
dff = df[df['Journal'].isin(options_chosen)] #dataframe with only selected journals
journals = dff['Journal'].value_counts().index.tolist() # --> x
journals_frequency = dff['Journal'].value_counts().tolist() # --> y
pie_journals = go.Pie(labels=journals, values=journals_frequency, showlegend=False, hole=0.5,textposition='inside',
name='Frequency of Journals',marker=dict(colors=color_charts_journals))
fig_pie_journals = go.Figure(data=[pie_journals])
fig_pie_journals.update_layout(title={
'text': "Frequency of journals",
'y':1,
'x':0.5,
'xanchor': 'center',
'yanchor': 'top'},
autosize=False,
width=450,
height=350,
margin=dict(t=20, b=15, l=5, r=5),)
#paper_bgcolor="LightSteelBlue") #per settare le dimensioni della torta
trace1 = go.Bar(y=journals, x=journals_frequency, orientation='h', name='Number of journals',
marker=dict(color=color_charts_journals)) # 'h' stays for horizontal
layout1 = go.Layout(autosize=False,
width=450,
height=350,
xaxis=dict(tickformat=',d', showgrid=False),
yaxis=dict(type='category', tickmode='linear', showticklabels=False, showgrid=False),
margin=dict(t=25,b=25,l=5,r=5),
bargap=0,
#paper_bgcolor="LightSteelBlue",
#per avere massimo 20 valori
#yaxis=dict(type='category', tickmode='auto', showgrid=False,
# automargin=False, nticks=20, tickwidth=10),
)
fig1 = go.Figure(data=[trace1], layout=layout1)#to set bar width
return fig_pie_journals,fig1
else:
return dash.no_update,dash.no_update
I'm creating a simple stock chart app in dash-plotly (python) whith an xaxis slider. When sliding the xaxis, I want the yaxis to dynamically rescale to the view. I think I have managed to get the callback function to trigger when sliding the xaxis scale through the 'relayoutData' hook. But instead of updating the yaxis the script throws errors. I'm not sure of the proper syntax to update layout from a callback function. Any ideas?
Here is my code so far. It runs, but yaxis is set at run time, and doesn't update.
Thanks a lot for any help =)
import dash
from dash.dependencies import Output, Input
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import numpy as np
import datetime
#some random values
a = datetime.datetime.today()
numdays = 100
dateList = []
for x in range (0, numdays):
dateList.append(a - datetime.timedelta(days = x))
xy = [dateList,np.random.rand(100)]
app = dash.Dash()
app.title = 'Random'
dataS = go.Scatter(
x = xy[0],
y = xy[1],
name = 'Rand',
mode = 'lines'
)
layoutS = go.Layout(
title="Rand",
xaxis=dict(
rangeslider_visible=True,
rangeselector=dict(
buttons=list([
dict(count=1, label="1m", step="month", stepmode="backward"),
dict(count=6, label="6m", step="month", stepmode="backward"),
dict(count=1, label="YTD", step="year", stepmode="todate"),
dict(count=1, label="1y", step="year", stepmode="backward"),
dict(count=5, label="5y", step="year", stepmode="backward"),
dict(step="all")
])
)
)
)
app.layout = html.Div(
html.Div([
html.H1(children='Random nums'),
html.Div(children='''
Rand rand rand.
'''),
dcc.Graph(id='RandGraph', animate=True, figure=go.FigureWidget(data=dataS,layout=layoutS))
])
)
#app.callback(Output('RandGraph','figure'),[Input('RandGraph','relayoutData')])
def update_graph(relOut):
layout = go.Layout(
yaxis=dict(range=[min(y),max(y)])
)
return {'layout':layout}
if __name__ == '__main__':
app.run_server(debug=False)
Here is the result. It I tried a serverside implementation first, which ended up being really slow (I kept it for reference). The clientside impletation is a lot more responsive and faster. A joy to use. I just needed to learn a bit of javascript to make if work =) I sure was missing pandas when I was trying to do the array filtering!
Here is the working code. Enjoy!
import dash
from dash.dependencies import Output, Input, State
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import numpy as np
import pandas as pd
import datetime
#some random values
a = datetime.datetime.today()
numdays = 100
dateList = []
for x in range (0, numdays):
dateList.append(a - datetime.timedelta(days = x))
xy = [dateList,np.random.rand(100)]
df = pd.DataFrame(data=xy[1],columns=["y"],index=xy[0])
#Graph data
dataS = [dict(
x = df.index,
y = df['y'],
name = 'meter',
mode = 'lines'
)]
#Graph layout
layoutS = go.Layout(
title="Meter",
xaxis=dict(
rangeslider_visible=True,
rangeselector=dict(
buttons=list([
dict(count=1, label="1m", step="month", stepmode="backward"),
dict(count=6, label="6m", step="month", stepmode="backward"),
dict(count=1, label="YTD", step="year", stepmode="todate"),
dict(count=1, label="1y", step="year", stepmode="backward"),
dict(count=5, label="5y", step="year", stepmode="backward"),
dict(step="all")
])
)
),
yaxis=dict(range=[0,2])
)
#Dash app layout
app = dash.Dash()
app.title = 'Random'
app.layout = html.Div(
html.Div([
html.H1(children='Random nums'),
html.Div(children='''
Rand rand rand.
'''),
dcc.Input(
id='input-y',
placeholder='Insert y value',
type='number',
value='',
),
html.Div(id='result'),
dcc.Graph(id='RandGraph',figure=dict(data=dataS,layout=layoutS))
])
)
#client side implementation
app.clientside_callback(
"""
function(relOut, Figure) {
if (typeof relOut !== 'undefined') {
if (typeof relOut["xaxis.range"] !== 'undefined') {
//get active filter from graph
fromS = new Date(relOut["xaxis.range"][0]).getTime()
toS = new Date(relOut["xaxis.range"][1]).getTime()
xD = Figure.data[0].x
yD = Figure.data[0].y
//filter y data with graph display
yFilt = xD.reduce(function (pV,cV,cI){
sec = new Date(cV).getTime()
if (sec >= fromS && sec <= toS) {
pV.push(yD[cI])
}
return pV
}, [])
yMax = Math.max.apply(Math, yFilt)
yMin = Math.min.apply(Math, yFilt)
} else {
yMin = Math.min.apply(Math, Figure.data[0].y)
yMax = Math.max.apply(Math, Figure.data[0].y)
}
} else {
yMin = Math.min.apply(Math, Figure.data[0].y)
yMax = Math.max.apply(Math, Figure.data[0].y)
}
Figure.layout.yaxis = {
'range': [yMin,yMax],
'type': 'linear'
}
return {'data': Figure.data, 'layout': Figure.layout};
}
""",
Output('RandGraph','figure'),
[Input('RandGraph','relayoutData')],[State('RandGraph', 'figure')]
)
#Server side implementation (slow)
##app.callback(
# Output('RandGraph','figure'),
# [Input('RandGraph','relayoutData')],[State('RandGraph', 'figure')]
#)
#def update_result(relOut,Fig):
# ymin = df.loc[relOut['xaxis.range'][1]:relOut['xaxis.range'][0],'y'].min()
# ymax = df.loc[relOut['xaxis.range'][1]:relOut['xaxis.range'][0],'y'].max()
# newLayout = go.Layout(
# title="OL Meter",
# xaxis=dict(
# rangeslider_visible=True,
# rangeselector=dict(
# buttons=list([
# dict(count=0, label="1m", step="month", stepmode="backward"),
# dict(count=6, label="6m", step="month", stepmode="backward"),
# dict(count=1, label="YTD", step="year", stepmode="todate"),
# dict(count=1, label="1y", step="year", stepmode="backward"),
# dict(count=5, label="5y", step="year", stepmode="backward"),
# dict(step="all")
# ])
# ),
# range=relOut['xaxis.range']
# ),
# yaxis=dict(range=[ymin,ymax])
# )
#
#
# Fig['layout']=newLayout
# return Fig
if __name__ == '__main__':
app.run_server(debug=False)
I have a table that I produced in plotly, and I want to change the font to 'Gill Sans'.
I am having trouble making it change. Is this possible?
This is my code:
groupA = new_df.groupby('Call').agg({'TotalGrantValue':sum, 'FirstReceivedDate':'count'}).rename(columns={'FirstReceivedDate':'Count'})
groupA['TotalGrantValue'] = groupA['TotalGrantValue'].map('{:,.2f}'.format)
colorscale = [[0, '#7f7f7f'],[.5, '#F1EDED'],[1, '#ffffff']]
table = ff.create_table(groupA, index=True,colorscale=colorscale, height_constant=14, index_title='Date')
table.layout.width = 700
for i in range(len(table.layout.annotations)):
table.layout.annotations[i].font.size = 10
plotly.offline.iplot(table, config={"displayModeBar": False}, show_link=False, filename='index_table_pd')
You need to define a layout parameter as stated in https://plot.ly/python/axes/.
from the same page, there is an example code that should help you:
layout = go.Layout(
xaxis=dict(
title='AXIS TITLE',
titlefont=dict(
family='Arial, sans-serif',
size=18,
color='lightgrey'
),
showticklabels=True,
tickangle=45,
tickfont=dict(
family='Old Standard TT, serif',
size=14,
color='black'
),
exponentformat='e',
showexponent='All'
),
yaxis=dict(
title='AXIS TITLE',
titlefont=dict(
family='Arial, sans-serif',
size=18,
color='lightgrey'
),
showticklabels=True,
tickangle=45,
tickfont=dict(
family='Old Standard TT, serif',
size=14,
color='black'
),
exponentformat='e',
showexponent='All'
)
)
fig = go.Figure(data=data, layout=layout)
py.iplot(fig, filename='axes-labels')