Hello guys i need help i have a piece of code that adds a list of horizontal lines to a Plotly figure in python. i want to change the code to were we will use a slider to add the horizontal lines to the figure and relayout it. As the slider moves right more horizontal lines will be added to the figure when the slider moves left the horizontal lines will be removed from the figure. Below is the bit of my code so far
for v in range(len(sortadlist)):
fig.add_hline(y=sortadlist[v][0], line_color='brown', line_width=1.5, row=1, col=1)
fig.add_shape(type="rect",
y0=round(sortadlist[v][0],2)-.3, y1=round(sortadlist[v][0],2)+.3, x0=-1, x1=len(df),
fillcolor="darkcyan",
opacity=0.15)
All the code above does is loop through a list of numbers and uses the fig.add_hline to add the horizontal line to the figure. I need help creating a slider that will add the horizontal lines to the figure
This is how the figure currently looks i want a slider to help with adding more horizontal lines to the figure and remove them also
Since the entire code is not available, the sample data was handled by obtaining the company's stock price. First of all, horizontal lines and shapes do not have a show/hide attribute, so they are not compatible with sliders. So I have created a code to draw a line according to the appropriate price list in the line chart of the scatter chart. Once the line chart is hidden, the first line chart is made visible.
The structure of the graph is a candlestick with 6 lines and the candlestick is always displayed. A loop process is used to create a list of lines to be shown or hidden.
import yfinance as yf
import plotly.graph_objects as go
import numpy as np
df = yf.download("AAPL", start="2022-01-01", end="2023-01-01", progress=False)
df.reset_index(inplace=True)
pricelist = np.arange(130,190,10)
fig = go.Figure()
fig.add_trace(go.Candlestick(x=df['Date'],
open=df['Open'],
high=df['High'],
low=df['Low'],
close=df['Close'],
name='AAPL'
)
)
fig.add_hrect(y0=df['Close'].median()-10,
y1=df['Close'].median()+10,
annotation_text="Median+-10",
annotation_position="top right",
fillcolor="darkcyan",
opacity=0.25,
line_width=0)
for p in pricelist:
fig.add_trace(go.Scatter(x=df['Date'],
y=[p]*len(df['Date']),
line_color='blue',
name=str(p),
showlegend=False,
visible=False,
)
)
fig.data[1].visible = True
steps = []
for i in np.arange(1,len(fig.data)):
step = dict(
method="update",
args=[{"visible": [False] * len(fig.data)},
{"title": "Price lines: " + str(pricelist[i-1])}],
label=str(pricelist[i-1])
)
step["args"][0]["visible"][0] = True
step["args"][0]["visible"][i] = True
steps.append(step)
sliders = [dict(
active=10,
currentvalue={"prefix": "Price: "},
pad={"t": 50},
steps=steps
)]
fig.update_layout(
sliders=sliders
)
fig.update_layout(height=600, xaxis_rangeslider_visible=False)
fig.show()
Related
I try to put scatter plot with secondary axis into Dash app and getting strange error. I tried many option but not sucsess... maybe you see whats wrong.
This is my code:
def scatter_1() -> dcc.Graph:
return dcc.Graph(
id="scatter-1",
figure2 = make_subplots(specs=[[{"secondary_y": True}]])
# Add traces
figure2.add_trace(
go.Scatter(set_df_f(),x="Testmantime", y="Speed1[Rpm]", name="yaxis data"),
secondary_y=False,
)
figure2.add_trace(
go.Scatter(set_df_f(),x="Testmantime", y='dda_50Amplitude', name="yaxis2 data"),
secondary_y=True,
)
# Add figure title
figure2.update_layout(
title_text="Double Y Axis Example"
)
# Set x-axis title
figure2.update_xaxes(title_text="xaxis title")
# Set y-axes titles
figure2.update_yaxes(title_text="<b>primary</b> yaxis title", secondary_y=False)
figure2.update_yaxes(title_text="<b>secondary</b> yaxis title", secondary_y=True)
)
Error in VSC says:
"(" was not closed",Pylance",LINE 31
line 31 is second line in the code i pasted: return dcc.Graph(
I dont get it, same syntax in jupyter work fine (difference is funcion import of dataframe). Appriciate your help.
Paulina
Here is CDF visualization I have:
fig_cdf = px.ecdf(df['Timespan'], color_discrete_sequence=['blue'],ecdfnorm='probability', orientation='h')
fig_cdf.add_hline(y=90, line_width=2, line_color="red", name='90%', visible=True)
fig_cdf.add_hline(y=30, line_width=2, line_color="red", name='75%', visible=True)
fig_cdf.update_layout(width=500, height=500)
The problem here is that i want horizontal lines' names to be visible and appear as 2nd and 3rd legends. For this, I tried to add visible=True. However, it seems not to work. What's wrong?
This is one way of doing it...
Add the two lines to the dataframe as new columns
Use color_discrete_sequence to identify the colors you want
I am using some random dummy data, which you can replace with your data
import plotly.express as px
df = pd.DataFrame({'firstline': random.sample(range(1, 500), 20),'myX' : range(20)}) #My dummy data
#Add the two lines to dataframe
df['90%'] = [90] * 20
df['75%'] = [75] * 20
fig = px.line(df,
y = ['firstline', '90%', '75%'], x= 'myX', color_discrete_sequence=["blue", "red", "red"])
fig.update_layout(legend_title_text='Legend Heading') #Update Legend header if you dont like 'variable'
fig.show()
Output graph
This is my first experience with this graph, but to add it to the legend, you can use the line mode of the scatter plot. So I took the maximum x-axis value used in the first graph and set the legend name Average using the appropriate y-axis value. This example is taken from the official reference.
import plotly.express as px
import plotly.graph_objects as go
df = px.data.tips()
fig = px.ecdf(df, x=["total_bill", "tip"])
xmax = max(fig.data[0]['x'])
#print(xmax)
fig.add_trace(go.Scatter(
x=[0,xmax],
y=[0.6,0.6],
mode='lines',
line_color='red',
name='mean',
showlegend=True
))
fig.show()
image of plotly chart
Hello, I'm really struggling to figure out how to format the axes on this chart. I've gone through the documentation and tried all sorts of different formatting suggestions from here and elsewhere but really not getting it. As you can see, the bottom chart has a .5 number, I want that to be skipped altogether and only have whole numbers along the axis.
I've seen ,d as a tickformat option to do this in about every answer, but I can't get that to work or I'm not seeing how to apply it to the second chart.
Can anyone with some Plotly charting experience help me out?
Here's the pertinent code:
def create_chart():
#Put data together into an interactive chart
fig.update_layout(height=500, width=800, yaxis_tickprefix = '$', hovermode='x unified', xaxis_tickformat =',d',
template=symbol_template, separators=".", title_text=(df.columns[DATA_COL_1]) + " & Units 2015-2019"
)
I believe what is happening is that the xaxis_tickformat parameter is affecting only the first subplot, but not the second one. To modify the formatting for each subplot, you can pass a dictionary with the tickformat parameter to yaxis, yaxis2, .... and so on for however many subplots you have (in your case, you only have 2 subplots).
import pandas as pd
from plotly.subplots import make_subplots
import plotly.graph_objects as go
## recreate the df
df = pd.DataFrame({'Year':[2015,2016,2017,2018,2019],
'Sales':[8.8*10**7,8.2*10**7,8.5*10**7,9.1*10**7,9.6*10**7],
'Units':[36200,36500,36900,37300,37700]})
def create_chart():
#Put data together into an interactive chart
fig = make_subplots(rows=2, cols=1)
fig.add_trace(go.Scatter(
x=df.Year,
y=df.Sales,
name='Sales',
mode='lines+markers'
), row=1, col=1)
fig.add_trace(go.Scatter(
x=df.Year,
y=df.Units,
name='Units',
mode='lines+markers'
), row=2, col=1)
fig.update_layout(
title_x=0.5,
height=500,
width=800,
yaxis_tickprefix = '$',
hovermode='x unified',
xaxis_tickformat =',d',
## this will change the formatting for BOTH subplots
yaxis=dict(tickformat ='d'),
yaxis2=dict(tickformat ='d'),
# template=symbol_template,
separators=".",
title={
'text':"MCD Sales & Units 2015-2019",
'x':0.5
}
)
fig.show()
create_chart()
Is it possible to add some text on the same html file as my plotly graph?
For example :
This is the code that generates a graph :
data = pd.read_csv('file.csv')
data.columns = ['price', 'place', 'date']
fig = px.scatter(data, x = "place", y = "price", )
fig.write_html("done.html")
This graph will generate a pyplot graph in an html file and I want to add some simple text (such as a conclusion line explaning the graph) under the graph.
This is an example of the output I would like:
ly
You can use fig.update_layout(margin=dict()) to make room for an explanation, and then fig.add_annotation() to insert any text you'd like below the figure utself to get this:
Complete code:
import plotly.graph_objects as go
import numpy as np
x = np.arange(-4,5)
y=x**3
yticks=list(range(y.min(), y.max(), 14))
#yticks.append(y.max())9
# build figure
fig = go.Figure(data=go.Scatter(x=x, y=y))
# make space for explanation / annotation
fig.update_layout(margin=dict(l=20, r=20, t=20, b=60),paper_bgcolor="LightSteelBlue")
# add annotation
fig.add_annotation(dict(font=dict(color='yellow',size=15),
x=0,
y=-0.12,
showarrow=False,
text="A very clear explanation",
textangle=0,
xanchor='left',
xref="paper",
yref="paper"))
fig.show()
In the following code block I use a Jupyter IntSlider to adjust the number of dots visualized in a Plotly express scatter 3d plot. The example already fits my use case, but I noticed that Plotly has built-in slider functionalities that could improve the performance.
As a Plotly beginner I find it quite hard to map the slider example from Plotly to my use case.
Any suggestions?
import numpy as np
import plotly.express as px
import pandas as pd
from ipywidgets import interact, widgets
NUM_DOTS = 100
NUM_DIMS = 3
random_data = pd.DataFrame(np.random.random((NUM_DOTS,NUM_DIMS) ), columns=['x_1','x_2','x_3'])
def update_plotly(x):
fig = px.scatter_3d(random_data[:x], x='x_1', y='x_2', z='x_3')
fig.show()
interact(update_plotly, x=widgets.IntSlider(min=1, max=NUM_DOTS, step=1, value=NUM_DOTS))
Actually it's not that hard to build the slider, just follow the path of the example shown by plotly:
import plotly.graph_objects as go
import numpy as np
NUM_DOTS = 100
NUM_DIMS = 3
# Create figure
fig = go.Figure()
# Add traces, one for each slider step
for step in np.arange(1, NUM_DOTS, 1):
#Random data
random_data = pd.DataFrame(np.random.random((step, NUM_DIMS)), columns=['x_1','x_2','x_3'])
fig.add_trace(
go.Scatter3d(
visible=False,
line=dict(color="#00CED1", width=6),
name="𝜈 = " + str(step),
z=random_data['x_3'],
x=random_data['x_1'],
y=random_data['x_2']))
# Make 10th trace visible
fig.data[10].visible = True
# Create and add slider
steps = []
for i in range(len(fig.data)):
step = dict(
method="restyle",
args=["visible", [False] * len(fig.data)],
)
step["args"][1][i] = True # Toggle i'th trace to "visible"
steps.append(step)
sliders = [dict(
active=10,
currentvalue={"prefix": "Frequency: "},
pad={"t": 50},
steps=steps
)]
fig.update_layout(
sliders=sliders
)
fig.show()
resulting:
or with more points:
As you correctly figured out, it is way more performant than the widget slider, because with this method, you just toggle the trace visibility in the 3D Scatter chart.