y2 axis selectable/dropdown range - python

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

Related

Plotly Scatter plot: how to create a scatter or line plot for only one group

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()

Creating a dropdown menu for Plotly

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()

Pandas - Stacked bar chart with multiple boolean columns

I have data like this. I would like to make a stacked bar chart where the x-axis is the ball color and each stack in the bar is the percentage of balls with that color that have that attribute (note each column in the bar chart will not sum to 100). I'm trying something like this
data = {'Ball Color' : ['Red', 'Blue', 'Blue', 'Red', 'Red', 'Red'],
'Heavy?' : [True, True, False, True, False, True],
'Shiny?' : [True, True, False, True, True, False]}
code_samp = pd.DataFrame(data)
code_samp.groupby('Ball Color')[['Heavy?', 'Shiny?']].value_counts().plot.bar()
But value_counts is only supported for series. Any ideas? Thanks in advance
Use:
code_samp.groupby('Ball Color').sum().plot.bar()
or
code_samp.groupby('Ball Color').mean().plot.bar()

Animated lineplot with python plotly

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()

heatmap and dendrogram (clustermap) error using Plotly

The last example in Plotly's documentation for Dendrograms has an error. When executing this code, I get this error in two locations due to 'extend':
AttributeError: ‘tuple’ object has no attribute ‘extend’
They are produced by these lines: figure.add_traces(heatmap) and figure['data'].extend(dendro_side['data'])
If anyone has run into this problem, please see my solution below! Happy coding!
I have a quick and accurate solution to run the last example code in Plotly's documentation for Dendrograms. Note that I am using Plotly offline in a Jupyter Notebook.
Figure has methods to add_traces, and these should replace extend.
The three key lines are :
figure.add_traces(dendro_side[‘data’])
figure.add_traces(heatmap)
plotly.offline.iplot(figure, filename=‘dendrogram_with_heatmap’)
Here is the full example code with my corrections and necessary imports, below:
# Import Useful Things
import plotly
import plotly.plotly as py
import plotly.graph_objs as go
import plotly.figure_factory as ff
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
plotly.offline.init_notebook_mode(connected=True)
import plotly.graph_objs as go
import plotly.figure_factory as ff
import numpy as np
from scipy.spatial.distance import pdist, squareform
# Get Data
data = np.genfromtxt("http://files.figshare.com/2133304/ExpRawData_E_TABM_84_A_AFFY_44.tab",names=True,usecols=tuple(range(1,30)),dtype=float, delimiter="\t")
data_array = data.view((np.float, len(data.dtype.names)))
data_array = data_array.transpose()
labels = data.dtype.names
# Initialize figure by creating upper dendrogram
figure = ff.create_dendrogram(data_array, orientation='bottom', labels=labels)
for i in range(len(figure['data'])):
figure['data'][i]['yaxis'] = 'y2'
# Create Side Dendrogram
dendro_side = ff.create_dendrogram(data_array, orientation='right')
for i in range(len(dendro_side['data'])):
dendro_side['data'][i]['xaxis'] = 'x2'
# Add Side Dendrogram Data to Figure
figure.add_traces(dendro_side['data'])
# Create Heatmap
dendro_leaves = dendro_side['layout']['yaxis']['ticktext']
dendro_leaves = list(map(int, dendro_leaves))
data_dist = pdist(data_array)
heat_data = squareform(data_dist)
heat_data = heat_data[dendro_leaves,:]
heat_data = heat_data[:,dendro_leaves]
heatmap = [
go.Heatmap(
x = dendro_leaves,
y = dendro_leaves,
z = heat_data,
colorscale = 'Blues'
)
]
heatmap[0]['x'] = figure['layout']['xaxis']['tickvals']
heatmap[0]['y'] = dendro_side['layout']['yaxis']['tickvals']
figure.add_traces(heatmap)
# Edit Layout
figure['layout'].update({'width':800, 'height':800,
'showlegend':False, 'hovermode': 'closest',
})
# Edit xaxis
figure['layout']['xaxis'].update({'domain': [.15, 1],
'mirror': False,
'showgrid': False,
'showline': False,
'zeroline': False,
'ticks':""})
# Edit xaxis2
figure['layout'].update({'xaxis2': {'domain': [0, .15],
'mirror': False,
'showgrid': False,
'showline': False,
'zeroline': False,
'showticklabels': False,
'ticks':""}})
# Edit yaxis
figure['layout']['yaxis'].update({'domain': [0, .85],
'mirror': False,
'showgrid': False,
'showline': False,
'zeroline': False,
'showticklabels': False,
'ticks': ""})
# Edit yaxis2
figure['layout'].update({'yaxis2':{'domain':[.825, .975],
'mirror': False,
'showgrid': False,
'showline': False,
'zeroline': False,
'showticklabels': False,
'ticks':""}})
# Plot using Plotly Offline
plotly.offline.iplot(figure, filename='dendrogram_with_heatmap')
This outputs:

Categories