Related
I have been trying to create a plotly figure (scatter plot) with a date slider and then exporting the figure to an HTML file.
To do so I have used the plotly px library: px.scatter(animation_frame...), just as in the second example here: https://plotly.com/python/sliders/.
Once I have the figure I save it to a HTML file with fig.to_html(full_html=False, include_plotlyjs='cdn').
This does work, but the problem I face is that the slider starts animating the frames by default whenever I open the html file. Is there a way to make the slider start static by default? I need it to start static because the figure has many frames and the slider automatically updating the frames makes the file really slow.
My code is:
figDVTO = px.scatter(dfPrueba, x="DíasVencimiento", y="Inflación", labels=dict(DíasVencimiento="Días al Vencimiento", Inflación="Inflación Implícita (%)"),
animation_frame="Fecha", title="Curva Inflación Implícita Diaria", range_y=[1, 8],
range_x=[0,7000], color = "Implícita", color_discrete_map = dicColores)
figDVTO.update_traces(marker=dict(size=12, line=dict(width=2,
color='DarkSlateGrey')),
selector=dict(mode='markers'))
I tried to set the "stop" animation button as default, but even when I do so, the slider animates the frames.
I also tried to construct the figure with plotly.graph_objects Figure, by constructing the dictionary that contains the frames.
I am able to recreate the figure I create with plotly express. However, after looking in plotly´s documentation I´m still no sure how to make the slider initially static. Have tried changing the method in updatemenus, as well as changing the method in sliders, but nothing seems to work.
I would really appreciate any sort of help, been scratching my head for weeks now...
Here is my complete code to construct the figure with plotly.graph_objects:
# make figure
fig_dict = {
"data": [],
"frames": [],
"layout": {'legend': {'title': {'text': 'Implícita'}, 'tracegroupgap': 0},
'sliders': [{
'active': 0,
'currentvalue': {'prefix': 'Fecha='},
'len': 0.9,
'pad': {'b': 10, 't': 60},
'steps':[],
'x': 0.1,
'xanchor': 'left',
'y': 0,
'yanchor': 'top'
}],
'title': {'text': 'Curva Inflación Implícita Diaria',
'font':dict(
family="Arial",
size=18,
)
},
'updatemenus': [{'active': 0,
'bgcolor': '#B0BEC5',
'buttons': [{'args': [None, {'frame': {'duration':
500, 'redraw': False},
'mode': 'immediate',
'fromcurrent': True,
'transition': {'duration':
500, 'easing': 'linear'}}],
'label': '▶',
'method': 'animate'},
{'args': [[None], {'frame':
{'duration': 0, 'redraw':
False}, 'mode': 'immediate',
'fromcurrent': True,
'transition': {'duration': 0,
'easing': 'linear'}}],
'label': '◼',
'method': 'animate'}],
'direction': 'left',
'pad': {'r': 10, 't': 70},
'showactive': True,
'type': 'buttons',
'x': 0.1,
'xanchor': 'right',
'y': 0,
'yanchor': 'top'}],
'xaxis': {'anchor': 'y',
'domain': [0.0, 1.0],
'range': [0, 7000],
'title': {'text': 'Días al Vencimiento'}},
'yaxis': {'anchor': 'x',
'domain': [0.0, 1.0],
'range': [1, 8],
'title': {'text': 'Inflación Implícita (%)'}}
}
}
#Creating starting frame
listFechas = list(dfPrueba['Fecha'].unique())
listImplicitas = list(dfPrueba['Implícita'].unique())
fecha=listFechas[0]
for implicita in listImplicitas:
data_dict = {
"x": np.array(dfPrueba.loc[(dfPrueba['Fecha']==fecha)&(dfPrueba['Implícita']==implicita), 'DíasVencimiento']),
"y": np.array(dfPrueba.loc[(dfPrueba['Fecha']==fecha)&(dfPrueba['Implícita']==implicita), 'Inflación']),
'legendgroup': str(implicita),
'hovertemplate': ('Implícita='+ str(implicita)+'<br>Fecha='+str(fecha)+'<br>Días al Vencimiento=%{x}<br>Inflación Implícita (%)=%{y}<extra></extra>'),
'marker': {'color': dicColores[implicita], 'line': {'color': 'DarkSlateGrey', 'width': 2}, 'size': 12, 'symbol': 'circle'},
"mode": "markers",
'marker': {'color': dicColores[implicita], 'line': {'color': 'DarkSlateGrey', 'width': 2}, 'size': 12, 'symbol': 'circle'},
"name": str(implicita),
'orientation': 'v',
'showlegend': True,
'type': 'scatter',
'xaxis': 'x',
'yaxis': 'y',
}
fig_dict["data"].append(data_dict)
# make frames
for fecha in listFechas:
frame = {"data": [], "name": str(fecha)}
for implicita in listImplicitas:
data_dict = {
"x": np.array(dfPrueba.loc[(dfPrueba['Fecha']==fecha)&(dfPrueba['Implícita']==implicita), 'DíasVencimiento']),
"y": np.array(dfPrueba.loc[(dfPrueba['Fecha']==fecha)&(dfPrueba['Implícita']==implicita), 'Inflación']),
'legendgroup': str(implicita),
'hovertemplate': ('Implícita='+ str(implicita)+'<br>Fecha='+str(fecha)+'<br>Días al Vencimiento=%{x}<br>Inflación Implícita (%)=%{y}<extra></extra>'),
'marker': {'color': dicColores[implicita], 'line': {'color': 'DarkSlateGrey', 'width': 2}, 'size': 12, 'symbol': 'circle'},
"mode": "markers",
'marker': {'color': dicColores[implicita], 'line': {'color': 'DarkSlateGrey', 'width': 2}, 'size': 12, 'symbol': 'circle'},
"name": str(implicita),
'orientation': 'v',
'legendgroup': '23',
'showlegend': True,
'type': 'scatter',
'xaxis': 'x',
'yaxis': 'y'
}
frame["data"].append(data_dict)
fig_dict["frames"].append(frame)
#Updating sliders steps
for fecha in listFechas:
loop_dic={'args': [[str(fecha)], {'frame':
{'duration': 0, 'redraw': False},
'mode': 'immediate', 'fromcurrent':
True, 'transition': {'duration': 0,
'easing': 'linear'}}],
'label': str(fecha),
'method': 'animate'}
fig_dict["layout"]["sliders"][0]["steps"].append(loop_dic)
#Creating figure
figB = go.Figure(fig_dict)
figB.update_layout(
title="Curva Inflación Implícita Diaria",
xaxis_title="Días al Vencimiento",
yaxis_title="Inflación Implícita (%)",
legend_title="Serie",
font=dict(
family="Arial",
size=18,
),
hovermode="x",
yaxis=dict(tickformat=".2f")
)
I would like to have the darkblue bar to start at 0, to be able to use it for negative and positive values.
Currently I don’t see how I could define that, judging by the reference.
https://plotly.com/python/reference/indicator/
https://plotly.com/python/bullet-charts/
import plotly.graph_objects as go
fig = go.Figure(go.Indicator(
mode = "number+gauge+delta", value = 10,
domain = {'x': [0, 1], 'y': [0, 1]},
delta = {'reference': 10, 'position': "top"},
title = {'text':"<b>Gearing</b><br><span style='color: gray; font-size:0.8em'>Finanical<br>Stability</span>", 'font': {"size": 14}},
gauge = {
'shape': "angular",
'axis': {'range': [-100, 100]},
'threshold': {
'line': {'color': "red", 'width': 2},
'thickness': 0.75, 'value': 70},
'bgcolor': "white",
'steps': [
{'range': [-100, 100], 'color': "cyan"},
{'range': [-50, 50], 'color': "royalblue"}],
'bar': {'color': "darkblue"}}))
fig.update_layout(height = 250)
fig.show()
This is showing value=10
This is showing value=0
This is showing value=-40
I found a way to simulate the appearance that you want to achieve using only steps. What I did is to hide the bar setting bar.thickness = 0 and then add an extra step with step.range = [0, value] and thickness <= 1.
I'm using Plotly.js, but the code should be similar.
const data = {
value: x
type: 'indicator',
mode: 'number+gauge',
gauge: {
shape: 'angular',
bar: { thickness: 0 },
steps: [
{
range: [-3500, 3500],
color: 'cyan',
thickness: 1,
},
{
range: [-1200, 1200],
color: 'royalblue',
thickness: 1,
},
{
range: [0, x],
color: 'blue',
thickness: 0.8,
},
]
},
}
Negative value
Positive value
I am going through the the slider animation plot tutorial from plotly (https://plot.ly/python/animations/), the one at the bottom, with my own data. My scenario is basically is data gathered from users from an application. I have data for one month (May), which the frequency of users are recorded hourly for each day. I want to use a slider to have a range of values from day 1 to 31 and the plot to show the unique values of each hour for each specific day.
My problem: I only get day one, but the value of the slider is updating correctly. Fixed old problem, now I have another one: Now instead of 1 step of the data, the graph is showing every single step.
My code:
# dMay to DataFrame
dfMay = pd.DataFrame({key :dMay[key] for key in list(dMay.keys())})
for i, df in enumerate([dfMay], 1):
df.columns = [str(col_name)[6:].format(i) for col_name in df.columns]
keys = list(map(lambda x: str(x), dfMay.keys())) # Slider values - days
from plotly.grid_objs import Grid, Column
listOfCols = []
for col in keys:
listOfCols.append(Column(dfMay[col], col))
grid = Grid(listOfCols)
py.grid_ops.upload(grid, 'Testing'+str(time.time()), auto_open=False)
# Animated Plot
figure = {
'data': [],
'layout': {},
'frames': []
}
# fill in most of layout
figure['layout']['xaxis'] = {'range': [0, 23], 'title': 'Zaman (saat)'}
figure['layout']['yaxis'] = {'title': 'Kullanıcı Sayısı', 'type': 'linear'}
figure['layout']['hovermode'] = 'closest'
figure['layout']['sliders'] = {
'args': [
'transition', {
'duration': 400,
'easing': 'cubic-in-out'
}
],
'initialValue': '0',
'plotlycommand': 'animate',
'values': list(range(24)),
'visible': True
}
figure['layout']['updatemenus'] = [
{
'buttons': [
{
'args': [None, {'frame': {'duration': 500, 'redraw': True},
'fromcurrent': True, 'transition': {'duration': 300, 'easing': 'quadratic-in-out'}}],
'label': 'Play',
'method': 'animate'
},
{
'args': [[None], {'frame': {'duration': 0, 'redraw': True}, 'mode': 'immediate',
'transition': {'duration': 0}}],
'label': 'Pause',
'method': 'animate'
}
],
'direction': 'left',
'pad': {'r': 10, 't': 87},
'showactive': False,
'type': 'buttons',
'x': 0.1,
'xanchor': 'right',
'y': 0,
'yanchor': 'top'
}
]
sliders_dict = {
'active': 0,
'yanchor': 'top',
'xanchor': 'left',
'currentvalue': {
'font': {'size': 20},
'prefix': 'Zaman:',
'visible': True,
'xanchor': 'right'
},
'transition': {'duration': 300, 'easing': 'cubic-in-out'},
'pad': {'b': 10, 't': 50},
'len': 0.9,
'x': 0.1,
'y': 0,
'steps': []
}
# make data
start = 0
for day in keys:
data_dict = {
'x': list(range(24)),
'y': list(dfMay[day]),
'mode': 'markers',
'marker': {
'sizemode': 'area',
'sizeref': 200000,
'size': 20
},
'name': day
}
figure['data'].append(data_dict)
# make frames
for day in keys:
frame = {'data': [], 'name': str(day)}
data_dict = {
'x': list(range(24)),
'y': list(dfMay[day]),
'mode': 'markers',
'text': list(dfMay[day]),
'marker': {
'sizemode': 'area',
'sizeref': 200000,
'size': 20
},
'name': day,
}
frame['data'].append(data_dict)
figure['frames'].append(frame)
slider_step = {'args': [
[day],
{'frame': {'duration': 1000, 'redraw': True},
'mode': 'immediate',
'transition': {'duration': 1000}}
],
'label': day,
'method': 'animate'}
sliders_dict['steps'].append(slider_step)
figure['layout']['sliders'] = [sliders_dict]
print('Done')
plot(figure)
I also can,t get rid of the colored markers on the right!
EDIT 1: Added dfMay Table
EDIT 2: Changed problem, added a new plot
Images to Supplement:
Fixes slider related issue. I followed another plotly tutorial. https://plot.ly/~empet/14896
plotData=[dict(type='scatter',
x=list(range(24)),
y=test_data[:0],
mode='markers',
marker=dict(size=10, color='red')
)
]
frames=[dict(data=[dict(y=test_data[:,k])],
traces=[0],
name=f'{k+1}',
layout=dict(yaxis=dict(range=[-1, test_data[:, k].max()+100]))) for k in range(31)]
sliders=[dict(steps= [dict(method= 'animate',
args= [[ f'{k+1}'],
dict(mode= 'e',
frame= dict( duration=1000, redraw= False ),
transition=dict( duration= 0)
)
],
label=f' {k+1}'
) for k in range(31)],
transition= dict(duration= 30 ),
x=0,#slider starting position
y=0,
currentvalue=dict(font=dict(size=12),
prefix='Day: ',
visible=True,
xanchor= 'center'
),
len=1.0,
active=1) #slider length)
]
axis_style=dict(showline=True,
mirror=True,
zeroline=False,
ticklen=4)
layout=dict(title='Mayıs-Günlük Kullanıcı Sayıları',
width=900,
height=600,
autosize=False,
xaxis=dict(axis_style, dtick=1, tit='s' title='Zaman (saat)', **dict(range=[0,24])),
yaxis=dict(axis_style, title='Kullanıcı Sayısı',autorange=False),
#plot_bgcolor="rgba(66,134,244, 0.2)",
shapes= [dict(
# Sabah
type= 'rect',
xref= 'x',
yref= 'paper',
x0= '0',
y0= 0,
x1= '8',
y1= 1,
fillcolor= 'rgba(66, 134, 244, 0.5)',
opacity= 0.2,
line= dict(width= 0)
),
# Oglen
dict(
type= 'rect',
xref= 'x',
yref= 'paper',
x0= '8',
y0= 0,
x1= '16',
y1= 1,
fillcolor= '#rgba(255, 252, 117,1)',
opacity= 0.2,
line= dict(width=0)
),
# Aksam
dict(
type= 'rect',
xref= 'x',
yref= 'paper',
x0= '16',
y0= 0,
x1= '24',
y1= 1,
fillcolor= 'rgba(2, 0, 168, 1)',
opacity= 0.2,
line= dict(width=0)
)
],
hovermode='closest',
updatemenus=[dict(type='buttons', showactive=True,
y=0,
x=1.15,
xanchor='right',
yanchor='top',
pad=dict(t=0, r=10),
buttons=[dict(label='Play',
method='animate',
args=[None,
dict(frame=dict(duration=4000,
redraw=True),
transition=dict(duration=4000),
fromcurrent=True,
mode='immediadate'
)
]
),
dict(label='Pause',
method='animate',
args=[[None],
dict(frame=dict(duration=0,
redraw=False),
transition=dict(duration=30),
fromcurrent=True,
mode='immediate'
)
]
)
]
)
],
sliders=sliders
)
# Animated Plot
figure = {
'data': plotData,
'layout': layout,
'frames': frames
}
fig=dict(data=plotData, frames=frames, layout=layout)
fig['data'][0].update(mode='markers+lines',
line=dict(width=1.5, color='blue'))
plot(fig, auto_open=False)
Displaying one slice of a numpy 3D array in Plotly is easy, just use a Heatmap:
import plotly.offline as offline
import plotly.graph_objs as go
import numpy as np
trace = go.Heatmap(z=3D_array[10,:,:]) # just one slice (10) along x axis
fig = dict(data=[trace])
offline.plot(fig, filename='heatmap.html')
What I want is to have a slider to see any slice. Using a few examples over the web I came up with this:
figure = {
'data': [],
'layout': {},
'frames': [],
}
sliders_dict = {
'active': 0,
'yanchor': 'top',
'xanchor': 'left',
'currentvalue': {
'font': {'size': 20},
'prefix': 'Year:',
'visible': True,
'xanchor': 'right'
},
'transition': {'duration': 300, 'easing': 'cubic-in-out'},
'pad': {'b': 10, 't': 50},
'len': 0.9,
'x': 0.1,
'y': 0,
'steps': []
}
frame = {'data': []}
for i in range(A.shape[0]):
frame['data'].append(A[i, :, :])
figure['frames'].append(frame)
slider_step = {'args': [
[i],
{'frame': {'duration': 300, 'redraw': False},
'mode': 'immediate',
'transition': {'duration': 300}}
],
'label': i,
'method': 'animate'}
sliders_dict['steps'].append(slider_step)
figure['layout']['sliders'] = [sliders_dict]
figure['data'] = [go.Heatmap(z=A[10,:,:])]
print(figure.keys())
offline.plot(figure, filename='heatmap.html')
I can't get it to work. I feel like there is a problem with passing data for consecutive frames.
Any tips on how to proceed?
I have this chart, created using python package xlsxwriter and I wanna remove all the points in the middle and only keep the first one and last one.
before :
Final results wanted.:
I tried the attribute points but unfortunate, it didn't work for me.
line_chart.add_series(
{
'values': '='+worksheet_name+'!$C$'+str(row_range+1)+':$I'+str(row_range+1),
'marker': {'type': 'diamond'},
'data_labels': {'value': True, 'category': True, 'position': 'center', 'leader_lines': True},
'points': [
{'fill': {'color': 'green'}},
None,
None,
None,
None,
None,
{'fill': {'color': 'red'}}
],
'trendline': {
'type': 'polynomial',
'name': 'My trend name',
'order': 2,
'forward': 0.5,
'backward': 0.5,
'line': {
'color': 'red',
'width': 1,
'dash_type': 'long_dash'
}
}
}
)
I also tried:
line_chart.set_x_axis({
'major_gridlines': {'visible': False},
'minor_gridlines': {'visible': False}
'delete_series': [1, 6]
})
no luck.
Anobody can help me please?
Thanks in advance!