I have a table that looks like below:
date
type
value_1
value_2
1/1
A
1
10
1/2
A
5
3
1/3
A
6
12
1/1
B
4
7
1/2
B
10
5
1/3
B
6
15
1/1
C
16
8
1/2
C
8
11
1/3
C
1
5
I want to draw a interactive graph for type A,B, and C so that 'date' column lies on the x-axis and 'value_1' and 'value_2' both lie on the y-axis in one graph.
The code I've currently wrote is below; I have used Plotly to plot Type A's value_1 and value_2 to be on the same plot with date as x-axis.
# Change Type (A, B, and C)
type_graph = 'A'
# Plot Graph
fig = px.line(df[df['type'] == type_graph ],
x='date', y=['value_1', 'value_2')
fig.update_layout(
title="Value graph",
xaxis_title="Date",
yaxis_title="Value_1 vs Value_2",
legend_title="Value Type",
)
fig.show()
I want to add dropdown menu so that I can change to view type B and C. So that instead of changing 'type_graph', I can just click the dropdown menu to select which 'type' I want to see.
In addition, I want value_1 and value_2 to be plotted on the same graph. As a result, I would only chose 'type' A, B, or C to see both value_1 and value_2 accordingly.
The desired button behavior is achieved by associating the display/hide of the graph with the type. So from your data, draw a graph of value_1 and a graph of value_2 and group them. Set the initial graphs to be displayed and make sure they are all displayed. Next, specify in the list whether the buttons should be shown or hidden as a function of the button. In this case, there are two graphs, so there will be two hidden. Refer to the reference here.
import plotly.graph_objects as go
fig = go.Figure()
for t in df['type'].unique():
dff = df[df['type'] == t]
fig.add_trace(go.Scatter(
x=dff.date,
y=dff['value_1'],
name='value_1',
legendgroup=t,
legendgrouptitle=dict(text=t),
visible=True,
))
fig.add_trace(go.Scatter(
x=dff.date,
y=dff['value_2'],
name='value_2',
legendgroup=t,
legendgrouptitle=dict(text=t),
visible=True,
))
fig.update_layout(
updatemenus=[
dict(
active=0,
buttons=list([
dict(label="All",
method="update",
args=[{"visible": [True, True, True, True, True, True]}]),
dict(label="Type_A",
method="update",
args=[{"visible": [True, True, False, False, False, False]}]),
dict(label="Type_B",
method="update",
args=[{"visible": [False, False, True, True, False, False]}]),
dict(label="Type_C",
method="update",
args=[{"visible": [False, False, False, False, True, True]}]),
]),
)
])
fig.update_layout(
autosize=True,
height=400,
title="Value graph",
xaxis_title="Date",
yaxis_title="Value_1 vs Value_2",
#legend_title="Value Type",
)
fig.show()
Related
new to python and programing.
I am trying to program some data visualization to improve efficiency.
I want to generate a scatter plot with plotly with y1 and y2. On y1 I want to have 2 permanent ranges of data. On y2 I want to have multiple data sets/ranges that can be selected to be shown or not.
Data is imported from an excel file.
I found a way, the other way around, to plot the permanent on y2 and on/off data on y1, but is not working great, legend is going crazy, format is changed to line plot and in the end this is not what I want, I want to have permanent data on y1 and selectable data on y2
import plotly.graph_objects as go
from plotly.subplots import make_subplots
fig = make_subplots(specs=[[{"secondary_y": True}]])
for column in df.columns.to_list():
fig.add_trace(
go.Scatter(x=df["Lap"],
y=df["P_TYR_FA (bar) mean"],name="TYR_FA"),secondary_y=False)
fig.add_trace(
go.Scatter(x=df["Lap"],
y=df["P_TYR_RA (bar) mean"],name="TYR_RA"),secondary_y=False)
fig.add_trace(
go.Scatter(x=df["Lap"],
y=df['P_INT (mbar) mean'],name="TYR_FR"),secondary_y=False)
fig.add_trace(
go.Scatter(x=df["Lap"],
y=df['P_FUE (bar) mean'],name="TYR_FF"),secondary_y=True)
fig.update_layout(
updatemenus=[go.layout.Updatemenu(
active=0,
buttons=list(
[dict(label = 'All',
method = 'update',
args = [{'visible': [True, True, True, True]},
{'title': 'All',
}]),
dict(label = 'P_TYR_FA',
method = 'update',
args = [{'visible': [True, False, False, True]}, # the index of True aligns with the indices of plot traces
{'title': 'MSFT',
}]),
dict(label = 'P_TYR_RA',
method = 'update',
args = [{'visible': [False, True, False, True]},
{'title': 'AAPL',
}]),
dict(label = 'P_INT',
method = 'update',
args = [{'visible': [False, False, True, True]},
{'title': 'AMZN',
}]),
dict(label = 'P_FUE',
method = 'update',
args = [{'visible': [False, False, False, True]},
{'title': 'GOOGL',
}]),
])
)
])
fig.update_layout(template="plotly_dark")
fig.show()
enter image description here
My question might seem very easy, but I am having a difficult time understanding how to create a scatter plot or line plot for only one group of values. For example, my data frame, has 3 columns.
My table looks like the following:
fruit
lb
price
orange
1
1.4
orange
2
1.7
apple
3
2.1
apple
1
1.4
kiwi
2
1.1
I want to create a scatter plot that has the lb as the x axis and price as the y axis. However, I only want to make the plot only for the orange category. What parameter should I use to specify the orange category?
What I have now is this:
px.scatter(df, x=df.lb, y=df.price)
Adding a user selection dropdown will accomplish your goal. Use a graph object to draw a graph for each type of fruit and show the Show/Hide setting. All and only each type will be available as a type of dropdown. Give the list of Show/Hide as input for the button. Now, the drop-down selection will toggle between show and hide. Please refer to the examples in the reference.
import plotly.graph_objects as go
fig = go.Figure()
for f in df['fruit'].unique():
dff = df.query('fruit == #f')
fig.add_trace(go.Scatter(mode='markers', x=dff.lb, y=dff.price, name=f, visible=True))
fig.update_layout(
updatemenus=[
dict(
active=0,
buttons=list([
dict(label="ALL",
method="update",
args=[{"visible": [True, True, True]},
{"title": "All fruit"}]),
dict(label="Orange",
method="update",
args=[{"visible": [True, False, False]},
{"title": "Orange"}]),
dict(label="Apple",
method="update",
args=[{"visible": [False, True, False]},
{"title": "Apple"}]),
dict(label="Kiwi",
method="update",
args=[{"visible": [False, False, True]},
{"title": "Kiwi"}]),
]),
)
])
fig.show()
fig = go.Figure()
for r in np.arange(0.05, 0.56, 0.005): #want the steps to show each value in r
xth_r,yth_r,zth_r = coords_theta(r)
fig.add_trace(
go.Scatter(mode="lines",
line=dict(color="#00CED1", width=2.5),
x=th,
y=magB(xth_r,yth_r,zth_r,xpos,ypos,zpos,0.1*165)))
fig.data[10].visible = True
steps = []
for i in range(len(fig.data)):
step = dict(
method="update",
args=[{"visible": [False] * len(fig.data)},
{"title": "R(m) is :" + str(i)}],
)
step["args"][0]["visible"][i] = True
steps.append(step)
sliders = [dict(
active=10,
currentvalue={"prefix": "R: "},
pad={"t": 50},
steps=steps
)]
fig.update_layout(
sliders=sliders
)
fig.show()
The steps show up as integer values, like step-0, step-6. I don't want this, I just want them to be the values in r. I would also like to have the area underneath the slider contain maybe like every 5 values of r, such that it doesn't get overcrowded with numbers.
Long post - I'm new to python and plotly, so appreciate the help!
I'm building a scatter plot with plotly using bike ride/workout data coming from a pandas dataframe with summary metrics (output/work, resistance, cadence/speed, etc.) as well as the length/duration for each ride. I'm trying to build in two features in particular into the scatter plot: 1) a dropdown menu to change/toggle the data displayed on the y-axis between 4 metrics fields (Total Output, Average Output, Average Cadence, and Average Resistance) and 2) a legend that represents data values mapped to discrete colors, in this case the ride.duration (each record/ride is either 5, 10, 20, 30, 45, or 60 min) and haven't been able to get both of them to do what I want at the same time.
I've been able to build a scatter plot with a dynamic y-axis dropdown and color the points according to the ride duration, but I can't get the ride duration legend to show up to indicate the color to duration mappings.
My code is below:
#test dataset - this is just a couple of points, so it won't look like the screenshots I've provided but should hopefully do the job!
all_rides_clean = pd.DataFrame(np.array([['a2662', '2022-04-24 18:09:25', 145,120,78,42,20,"Ben"],
['b10e', '2022-03-21 11:28:20', 128,71,66,35,30,"Emma"],
['850g', '2021-01-19 11:29:31',121,101,80,38,45,"Leanne"],
['897b','2021-09-21 22:46:30',175,65,54,37,60,"Emma"]]),
columns=['id','created_at','Total Output','Avg Output','Avg Cadence','Average Resistance','ride.duration',
'instructor.name'])
all_ride[['Total Output','Avg Output','Avg Cadence','Avg Resistance']] = all_ride[['Total Output','Avg Output','Avg Cadence','Avg Resistance']].apply(pd.to_numeric)
fig = go.Figure()
# dynamic y-axis dropdown labels
metrics = ['Total Output','Avg Output','Avg Cadence','Avg Resistance']
# make list of default plotly colors in hex
plotly_colors=[
'#1f77b4', # muted blue
'#ff7f0e', # safety orange
'#2ca02c', # cooked asparagus green
'#d62728', # brick red
'#9467bd', # muted purple
'#8c564b', # chestnut brown
'#e377c2', # raspberry yogurt pink
'#7f7f7f', # middle gray
'#bcbd22', # curry yellow-green
'#17becf' # blue-teal
]
# create dictionary to associate colors with unique categories
color_dict = dict(zip(all_rides_clean['ride.duration'].unique(),plotly_colors))
# map new column with hex colors to pass to go.Scatter()
all_rides_clean['hex']= all_rides_clean['ride.duration'].map(color_dict)
for column in metrics:
fig.add_trace(
go.Scatter(
x = all_rides_clean['created_at'],
y = all_rides_clean[column],
name = column,
mode = 'markers',
#setting color legend
marker=dict(color=all_rides_clean['hex']),
showlegend=False
)
)
fig.update_layout(
updatemenus=[go.layout.Updatemenu(
active=0,
buttons=list(
[dict(label = 'Total Output',
method = 'update',
args = [{'visible': [True, False, False, False]}, # the index of True aligns with the indices of plot traces
{'title': 'Total Output',
'showlegend':False}]),
dict(label = 'Avg Output',
method = 'update',
args = [{'visible': [False, True, False, False]},
{'title': 'Avg Output',
'showlegend':False}]),
dict(label = 'Avg Cadence',
method = 'update',
args = [{'visible': [False, False, True, False]},
{'title': 'Avg Cadence',
'showlegend':False}]),
dict(label = 'Avg Resistance',
method = 'update',
args = [{'visible': [False, False, False, True]},
{'title': 'Avg Resistance',
'showlegend':False}]),
])
)
],
)
fig.show()
This code produces the following chart:
And as you can see, the y-axis toggle works and the scatter points are colored correctly, but I can't seem to get the color legend to show up to show which colors represent which ride duration. I've tried messing around with showLegend, but that only seems to control the dropdown legend for each trace (for output, resistance, and cadence).
I've been able to get a ride duration color legend to display when I use plotly express and hard code one of the workout metrics values to the y-axis, like so:
fig = px.scatter(all_rides_clean, x='created_at', y='Total Output',color="ride.duration")
but that isn't what I'm looking for because I want the dropdown / ability to dynamically change what's displayed on the y-axis between the different output, resistance, and cadence values.
Anyone know how to get this color legend to display?
Ultimately, I would also like to add another dropdown to be able to dynamically change the discrete data displayed in the color legend (between ride duration, ride type, etc.), so any tips here welcomed.
Thanks in advance!
I have gold price dataset , where first column is date on yyyy-mm-dd format and the second column is gold price.
2019-12-03 1477.60
2019-12-04 1474.45
2019-12-05 1448.40
Is there any way to make animation lineplot with python plotly where I can show gold price change along with date?
Yes, I show you an example.
The effect is fancy but you don't gain much because it is a two dimensional data, I could say indeed you are delaying the data display with no reason.
Usually animations are nice for showing 3 dimensions and obviously using the time as extra dimension to perform the animation, like the first example at plotly web animation documentation: https://plotly.com/python/animations/
import plotly.graph_objects as go
import pandas as pd
# Maybe you needed to display plot in jupyter notebook
import plotly.offline as pyo
pyo.init_notebook_mode()
# Load exmples data
dates = ["2019-12-03", "2019-12-04", "2019-12-05", "2019-12-06",
"2019-12-07", "2019-12-08", "2019-12-09"]
value_gold = [1477.60, 1474.45, 1448.40, 1447.40, 1444.40, 1449.40, 1441.40]
value_bitcoin = [1577.60, 1564.45, 1568.40, 1537.40, 1584.40, 1529.40, 1571.40]
df = pd.DataFrame(list(zip(dates, value_gold, value_bitcoin)),
columns=['date', 'value_gold', 'value_bitcoin'])
# Base plot
fig = go.Figure(
layout=go.Layout(
updatemenus=[dict(type="buttons", direction="right", x=0.9, y=1.16), ],
xaxis=dict(range=["2019-12-02", "2019-12-10"],
autorange=False, tickwidth=2,
title_text="Time"),
yaxis=dict(range=[1400, 1600],
autorange=False,
title_text="Price"),
title="Gold - Bitcoin prices evolution",
))
# Add traces
init = 1
fig.add_trace(
go.Scatter(x=df.date[:init],
y=df.value_gold[:init],
name="Gold",
visible=True,
line=dict(color="#33CFA5", dash="dash")))
fig.add_trace(
go.Scatter(x=df.date[:init],
y=df.value_bitcoin[:init],
name="Bitcoin",
visible=True,
line=dict(color="#bf00ff", dash="dash")))
# Animation
fig.update(frames=[
go.Frame(
data=[
go.Scatter(x=df.date[:k], y=df.value_gold[:k]),
go.Scatter(x=df.date[:k], y=df.value_bitcoin[:k])]
)
for k in range(init, len(df)+1)])
# Extra Formatting
fig.update_xaxes(ticks="outside", tickwidth=2, tickcolor='white', ticklen=10)
fig.update_yaxes(ticks="outside", tickwidth=2, tickcolor='white', ticklen=1)
fig.update_layout(yaxis_tickformat=',')
fig.update_layout(legend=dict(x=0, y=1.1), legend_orientation="h")
# Buttons
fig.update_layout(
updatemenus=[
dict(
buttons=list([
dict(label="Play",
method="animate",
args=[None, {"frame": {"duration": 1000}}]),
dict(label="Gold",
method="update",
args=[{"visible": [False, True]},
{"showlegend": True}]),
dict(label="Bitcoin",
method="update",
args=[{"visible": [True, False]},
{"showlegend": True}]),
dict(label="All",
method="update",
args=[{"visible": [True, True, True]},
{"showlegend": True}]),
]))])
fig.show()