Default display of annotations in Plotly/Python using a button - plotly-python

I managed the possibility to switch on and off the annotations in a plotly chart. After the executing the code i would like to see the chart without annotations and if required, the annotations could be activated (Label: OFF).
The following code displays per default the annotations and i am not able to set it up, that the first display of chart will be show without annotations.
import plotly.express as px
import pandas as pd
# assign data of lists.
data = {'x': ["2022-05-06", "2022-05-08", "2022-05-09", "2022-05-12", "2022-05-15", "2022-05-16", "2022-05-22", "2022-05-24", "2022-05-26"],
'y': [0, 1, 8, 2, 4, 3, 4, 6, 5],
'text':["","","Annotation1","","Annotation2","","","","Annotation3"]}
# Create DataFrame
df = pd.DataFrame(data)
# assign data of lists.
data1 = {'x': ["2022-05-07", "2022-05-14", "2022-05-23"],
'text':["Annotation1", "Annotation2", "Annotation3"]}
df1 = pd.DataFrame(data1)
fig = px.line(df, x='x', y='y', title='Annotations ONN / OFF')
arrow_list=[]
counter=0
for i in df1['text'].tolist():
if i != "":
arrow=dict(x=df1['x'].values[counter],y=9,xref="x",yref="y",text=i,arrowhead = 2,ax=0,
arrowwidth=1.5,
bordercolor="#c7c7c7",
borderwidth=2,
borderpad=4,
bgcolor="#ff7f0e",
opacity=0.8,
font=dict(
family="Courier New, monospace",
size=16,
color="#ffffff"
),
arrowcolor='rgb(255,51,0)',)
arrow_list.append(arrow)
counter+=1
else:
counter+=1
fig.update_layout(
updatemenus=[
dict(
type="buttons",
# direction="right",
active=0,
showactive=True,
buttons=list([
dict(label="Label:Off",
method="update",
args=[{"visible": [True, False, True, False]},
{"annotations": []}]),
dict(label="Label:On",
method="update",
args=[{"visible": [True, True, True, True]},
{"annotations": arrow_list}]),
]),
)
])
fig.update_layout(annotations=arrow_list)
fig.show()
I have tried to modify args and active, but without any success.
The first display of the charts (annotations should be off):

I found the solution:
import plotly.graph_objects as go
import pandas as pd
# Load dataset
# assign data of lists.
data = {'Date': ["2022-05-06", "2022-05-08", "2022-05-09", "2022-05-12", "2022-05-15", "2022-05-16", "2022-05-22", "2022-05-24", "2022-05-26"],
'High': [0, 1, 8, 2, 4, 3, 4, 6, 5],
'text':["","","Annotation1","","Annotation2","","","","Annotation3"]}
# Create DataFrame
df = pd.DataFrame(data)
# Initialize figure
fig = go.Figure()
# Add Traces
fig.add_trace(
go.Scatter(x=list(df.Date),
y=list(df.High),
name="High",
line=dict(color="#33CFA5")))
arrow_list=[]
counter=0
for i in df1['text'].tolist():
if i != "":
arrow=dict(x=df1['x'].values[counter],y=9,xref="x",yref="y",text=i,arrowhead = 2,ax=0,
arrowwidth=1.5,
bordercolor="#c7c7c7",
borderwidth=2,
borderpad=4,
bgcolor="#ff7f0e",
opacity=0.8,
font=dict(
family="Courier New, monospace",
size=16,
color="#ffffff"
),
arrowcolor='rgb(255,51,0)',)
arrow_list.append(arrow)
counter+=1
else:
counter+=1
fig.update_layout(
updatemenus=[
dict(
active=0,
buttons=list([
dict(label="Label: Off",
method="update",
args=[{"visible": [True, False, True, False]},
{"title": "Labels Off",
"annotations": []}]),
dict(label="Label: On",
method="update",
args=[{"visible": [True, True, False, False]},
{"title": "Labels On",
"annotations": arrow_list}]),
]),
)
])
fig.show()

Related

Plotly Dropdown not updating graphs correctly

I am working on creating dropdown menu for my data
here is my data
data = {'Time': [2,4,5,6,7], 'Voltage': [20.3, 17.2,15.3,9.4,2], "Current":[2, 5,7,8,9]}
df = pd.DataFrame(data)
this is the code for plotting dropdowns
plot = px.Figure(data=[go.Scatter(
name='Voltage',
x=df["Time"],
y=df["Voltage"]
),
go.Scatter(
name='Data 2',
x=df["Time"],
y=df["Current"]
)
])
plot.update_layout(
updatemenus=[
dict(
buttons=list([
dict(label="Voltage",
method="update",
args=[{"visible": [True, False]},
{"title": "Voltage",
}]),
dict(label="Current",
method="update",
args=[{"visible": [False, True]},
{"title": "Data 2",
}]),
]),
)
])
plot.show()
even though i am not selecting both plots to display it is showing both plots how to overcome this
thanks and regards
You need to add visible = Falseto second scatter. So it should be :
go.Scatter(
name='Data 2',
x=df["Time"],
y=df["Current"] ,
visible = False)
Your code defines the two scatter plots as one graph, so if you rewrite it to set up two graphs, the buttons are not set up incorrectly and the graph can be changed by the drop down buttons.
import plotly.graph_objects as go
fig = go.Figure()
fig.add_trace(go.Scatter(name='Voltage', x=df["Time"], y=df["Voltage"], line_color='blue'))
fig.add_trace(go.Scatter(name='Data 2', x=df["Time"], y=df["Current"], line_color='red'))
fig.update_layout(
updatemenus=[
dict(
buttons=list([
dict(label="Voltage",
method="update",
args=[{"visible": [True, False]},
{"title": "Voltage",
}]),
dict(label="Current",
method="update",
args=[{"visible": [False, True]},
{"title": "Data 2",
}]),
]),
)
])
fig.show()

Convert pandas dataframe to datasetDict

I cannot find anywhere how to convert a pandas dataframe to type datasets.dataset_dict.DatasetDict, for optimal use in a BERT workflow with a huggingface model. Take these simple dataframes, for example.
train_df = pd.DataFrame({
"label" : [1, 2, 3],
"text" : ["apple", "pear", "strawberry"]
})
test_df = pd.DataFrame({
"label" : [2, 2, 1],
"text" : ["banana", "pear", "apple"]
})
What is the most efficient way to convert these to the type above?
One possibility is to first create two Datasets and then join them:
import datasets
import pandas as pd
train_df = pd.DataFrame({
"label" : [1, 2, 3],
"text" : ["apple", "pear", "strawberry"]
})
test_df = pd.DataFrame({
"label" : [2, 2, 1],
"text" : ["banana", "pear", "apple"]
})
train_dataset = Dataset.from_dict(train_df)
test_dataset = Dataset.from_dict(test_df)
my_dataset_dict = datasets.DatasetDict({"train":train_dataset,"test":test_dataset})
The result is:
DatasetDict({
train: Dataset({
features: ['label', 'text'],
num_rows: 3
})
test: Dataset({
features: ['label', 'text'],
num_rows: 3
})
})

Python 3 matplotlit figure saved broken

I use the python 3 to make a figure, it displays very well, but when I save it, it is broken for the right half, as figures appended below. I am not sure what is wrong with it. The code I have is the following:
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import rcParams, AutoMinorLocator
params = {'backend': 'ps',
'font.size': 30,
'font.style': 'normal',
'axes.labelsize': 30,
#'text.fontsize': 30,
'axes.linewidth': 2,
'legend.fontsize': 12,
'xtick.labelsize': 30,
'ytick.labelsize': 30,
'xtick.top': True,
'ytick.right': True,
#'xtick.major.top': True,
#'xtick.minor.top': True,
#'ytick.major.right': True,
#'ytick.minor.right': True,
'text.usetex': True,
'ps.usedistiller': 'xpdf'}
rcParams.update(params)
ion = [-2.0, -2.5, -3.0, -3.25, -3.5, -4.0, -4.5, -5.0, -5.5, -6.0]
cooling_mass = [0.036409, 0.035329, 0.042622, 0.069795, 0.090708, 0.107212, 0.109671, 0.110513, 0.107213, 0.109558]
fig, ax = plt.subplots(1, figsize=(8,6))
minor_locator1 = AutoMinorLocator(5)
ax.xaxis.set_minor_locator(minor_locator1)
minor_locator2 = AutoMinorLocator(5)
ax.yaxis.set_minor_locator(minor_locator2)
ax.tick_params('both', length=10, width=2, direction='in',which='major',pad=8)
ax.tick_params('both', length=5, width=2, direction='in',which='minor',pad=8)
ax.axhspan(0.036, 0.107, facecolor='lightskyblue', alpha=0.5)
ax.scatter(ion, cooling_mass, color='b', marker = 'o', s=50, zorder=2)
ax.set_ylim([0.008,0.14])
ax.set_yticks([0.03,0.06,0.09,0.12])
ax.set_xlim([-6.5,-1.5])
ax.set_xticks([-6.0,-4.0,-2.0])
ax.set_ylabel(r'$\rm Cooling ~Mass ~Rate ~[\rm M_\odot/yr]$', size=20, labelpad=5)
ax.set_xlabel(r'$\log {\rm U}$')
plt.gca().invert_xaxis()
plt.savefig('ion_cooling.eps',bbox_inches='tight')
plt.show()

Ordering seaborn heatmap xticks given certain values

I have this given data:
import matplotlib.pyplot as plt
from matplotlib.patches import Patch
import seaborn as sns
import pandas as pd
df = pd.DataFrame({'C': np.random.choice([False, False, False, True], 100000),
'D': np.random.choice([False,True], 100000),
'B': np.random.choice([False,True, True], 100000),
'A': np.random.choice([False, False, True], 100000),
'F': np.random.choice([False,True, True, True], 100000)})
Where I plot this:
fig, ax = plt.subplots(figsize=(5, 6))
cmap = sns.mpl_palette("Set2", 2)
sns.heatmap(data=df, cmap=cmap, cbar=False)
plt.xticks(rotation=90, fontsize=10)
plt.yticks(rotation=0, fontsize=10)
legend_handles = [Patch(color=cmap[True], label='Missing Value'), # red
Patch(color=cmap[False], label='Non Missing Value')] # blue-green
plt.legend(handles=legend_handles, ncol=2, bbox_to_anchor=[0.5, 1.02], loc='lower center', fontsize=8, handlelength=.8)
plt.tight_layout()
plt.show()
I have been trying to order the x-axis from higher to lower (left to right) given the count of True values. So, the first position should have the highest amount of True values, the second position the second highest, and so on.
I was able to get the positions and their respective labels with:
x_axis = df.sum().rank(method="dense", ascending=False)
x_pos = x_axis.values.tolist()
x_labels = x_axis.index.tolist()
But I'm struggling trying to put this in the plot and make it work, and also because I need to be sure that I'm not just changuing the position of the labels but also the position of the variables displayed in the plot (as I'm visualizing near 100 variables in the real dataframe)
You can extract order then reindex:
orders = df.sum().sort_values(ascending=False).index
# change this:
sns.heatmap(data=df.reindex(orders, axis=1), cmap=cmap, cbar=False)
Output:

Return a graph based on a value from the dropdown

I am trying to plot a matplotlib graph after based on the value chosen from the dropdown. I have made the dropdown and the plots are also ready for the values but i dont know how to connect both of them together.
Following is the code of the dropdown:
app.layout = html.Div([
dcc.Dropdown(
id='first-dropdown',
options = [
{'label': 'Chest Pain', 'value': 'cp'},
{'label': 'Resting Blood Pressure', 'value': 'trestbps'},
{'label': 'Serum Cholestrol in mg/dl', 'value': 'chol'},
{'label': 'Fasting Blood Pressure', 'value': 'fbs'},
{'label': 'Resting electrocardiographic results', 'value': 'restecg'},
{'label': 'Maximum heart rate achieved', 'value': 'thalach'},
{'label': 'Exercise induced angina', 'value': 'exang'},
{'label': 'Old Peak', 'value': 'oldpeak'},
{'label': 'Slope of the peak exercise ST segment', 'value': 'slope'},
{'label': 'Number of major vessels (0-3) colored by flourosopy', 'value': 'ca'},
{'label': 'Thalassemia', 'value': 'thal'}
],
value= 'thalach'
)
])
and for each value in the dropdown i have a separate function which returns a plot. For eg:
What i am trying to do is that if the Label 'Max Heart Rate Achieved' is selected from the dropdown whose value is 'thalach'. I have a function called plotThalach which returns a plot like this:
def plotThalach(df):
df_men = df[df['sex'] == 1.0]
df_women = df[df['sex'] == 0.0]
plt.figure(figsize=(20, 8))
plt.bar(df_men['age'] + 0.00, df_men['thalach'], color='b', width=0.25, label='Men')
plt.bar(df_women['age'] + 0.25, df_women['thalach'], color='r', width=0.25, label='Women')
plt.legend(loc='upper right')
plt.xlabel("Age")
plt.ylabel("Max Heart Rate")
plt.title("Age vs Max Heart Rate")
return plt
Now how do i connect both of these in such a way that when a value is selected from the dropdown my function gets called and plot gets displayed on the screen.
It's not so clear why you want to mix plotly-dash and matplotlib, you can easily do it using just plotly-dash
Here is a sample code,
import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output
import pandas as pd
import plotly.graph_objs as go
df = pd.read_csv(
'https://raw.githubusercontent.com/plotly/'
'datasets/master/gapminderDataFiveYear.csv')
external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
#main div
app.layout = html.Div([
#drop down with a default value set
dcc.Dropdown(
id='xaxis-column',
options=[{'label': str(year), 'value': year} for year in df['year'].unique()],
value=df['year'].min(),
),
#graph that is to be updated
dcc.Graph(id='graph-with-slider')
])
#callback which will be spawned when the input changes, in this case the input is the dropdown value
#app.callback(
Output('graph-with-slider', 'figure'),
[Input('xaxis-column', 'value')])
def update_figure(selected_year):
filtered_df = df[df.year == selected_year]
traces = []
for i in filtered_df.continent.unique():
df_by_continent = filtered_df[filtered_df['continent'] == i]
traces.append(go.Scatter(
x=df_by_continent['gdpPercap'],
y=df_by_continent['lifeExp'],
text=df_by_continent['country'],
mode='markers',
opacity=0.7,
marker={
'size': 15,
'line': {'width': 0.5, 'color': 'white'}
},
name=i
))
return {
'data': traces,
'layout': go.Layout(
xaxis={'type': 'log', 'title': 'GDP Per Capita'},
yaxis={'title': 'Life Expectancy', 'range': [20, 90]},
margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
legend={'x': 0, 'y': 1},
hovermode='closest'
)
}
if __name__ == '__main__':
app.run_server(debug=True)
But if you want to show the matplotlib graph instead of plotly-dash graph, you can refer the "Incorporating Matplotlib Plots" section here