Combined xaxis and header of table with plotly Python - python

I would like to do something quite similar to the picture with plotly on python. I tried to find a way with subplots and shared_axis but no way to find a correct way. Is it possible to share the x axis of a bar chart with the column titles of a table?
graph bar with shared xaxis

this can be simulated with two traces
first trace is a standard bar chart, with yaxis domain constrained to 80% of the figure
second trace is a bar showing values as text and a fixed height against a second yaxis. yaxis2 is constrained to 10% of the domain
import plotly.express as px
import pandas as pd
import numpy as np
df = pd.DataFrame({"year": range(2011, 2022)}).assign(
pct=lambda d: np.random.uniform(-0.08, 0.08, len(d))
)
px.bar(df, x="year", y="pct").add_traces(
px.bar(df, x="year", y=np.full(len(df), 1), text="pct")
.update_traces(
yaxis="y2",
marker={"line": {"color": "black", "width": 1.5}, "color": "#E5ECF6"},
texttemplate="%{text:,.2%}",
)
.data
).update_layout(
yaxis={"domain": [0.2, 1], "tickformat": ",.2%"},
yaxis2={"domain": [0, 0.1], "visible": False},
xaxis={"title": "", "dtick": 1},
)

Related

How do you set the opacity of a Plotly Chart's bars individually?

I'm working on bar chart using plotly express. I'd like to use discrete colours and set the opacity of each bar individually. At the moment I'm using the following code:
import plotly.express as px
df1 = pd.DataFrame(dict(score=[93.3, 93.3, 92, 88], model=['model1', 'model2', 'model3', 'model4']))
fig = px.bar(df1, x='score', y='model', color='model',
color_discrete_map={
"model1": "gray",
"model2": "rgb(255, 10, 10)",
"model3": "rgb(255, 10, 10)",
"model4": "rgb(255, 10, 10)"},
opacity=[1, 1, 0.1, 0.1])
fig.update_layout(xaxis_range=[80,100], xaxis_title='Score', yaxis_title='')
fig.show()
To generate the plot below:
I've tried adding separate opacities using a list of values, but that doesn't seem to work. Instead, plotly takes the first value in the list and applies it to all the bar charts.
How can I add opacity to each bar individually?
I have not verified that this technique works for all plotly, but you can set the alpha value in the format 'rgba(255,10,10,0.5)' in the color specification.
import plotly.express as px
import pandas as pd
df1 = pd.DataFrame(dict(score=[93.3, 93.3, 92, 88], model=['model1', 'model2', 'model3', 'model4']))
fig = px.bar(df1, x='score', y='model', color='model',
color_discrete_map={
"model1": "gray",
"model2": "rgb(255, 10, 0)",
"model3": "rgba(255, 10, 10, 0.5)",
"model4": "rgba(255, 10, 10, 0.3)"},
#opacity=[1, 1, 0.1, 0.1]
)
fig.update_layout(xaxis_range=[80,100], xaxis_title='Score', yaxis_title='')
fig.show()
This can be done by digging deeper into plotly's Bar object.
Import plotly.graph_objects along with plotly.express with the following code:
import plotly.express as px
import plotly.graph_objects as go
With those imported you can create the chart object and then add the bars one by one to get the result you want:
# Create the initial bar chart
fig = px.bar()
# Add the bar chart for model 1, set its opacity to 0.3
fig.add_trace(
go.Bar(
x=[88],
y=['model1'],
opacity=0.3,
orientation='h',
marker=dict(color='rgb(255, 10, 10)')
)
)
# Add the bar chart for model 2, set its opacity to 0.65
fig.add_trace(
go.Bar(
x=[92],
y=['model2'],
opacity=0.65,
orientation='h',
marker=dict(color='rgb(255, 10, 10)')
)
)
fig.show()
This will give you something like the following:
As you can see, newly added bars automatically go to the top of the chart, so bare that in mind when you're setting up your own chart.

Is there an easy way to add a secondary y-axis to a Plotly plot without the need of providing a second array?

I want to have two y-axes for the same time series, an axis with the absolute number as values, and an axis with the percentages as values. Draft schematics of the desired outcome
I don't see a way of doing it without 2 traces. It does mean each trace can be switched on / off in legend so that hover gives interactivity.
import numpy as np
import pandas as pd
import plotly.graph_objects as go
x = pd.date_range("14-feb-2022", freq="1H", periods=400)
y = np.sort(np.random.pareto(2, 400))[::-1]
go.Figure(
[
go.Scatter(x=x, y=y, name="abs"),
go.Scatter(
x=x,
y=y / y.max(),
name="% max",
yaxis="y2",
),
],
layout={
"yaxis2": {
"side": "right",
"tickformat": ",.0%",
},
"yaxis": {"overlaying": "y2"},
"legend": {"orientation": "h", "xanchor": "center", "x": 0.5},
},
)

matplotlib to plotly plot conversion

I wanted to create an interactive plot with matplotlib in google colab. It seems like a complex task so I want a little help to convert this piece of code which is in matplotlib to Plotly.
close = df['A']
fig = plt.figure(figsize = (15,5))
plt.plot(close, color='r', lw=2.)
plt.plot(close, '^', markersize=10, color='m', label = 'signal X', markevery = df_x)
plt.plot(close, 'v', markersize=10, color='k', label = 'signal Y', markevery = df_y)
plt.title('Turtle Agent: total gains %f, total investment %f%%'%(df_A, df_B))
plt.legend()
plt.show()
using sample data from plotly OHLC examples https://plotly.com/python/ohlc-charts/
create a line trace
add scatter traces based on filters of data frame with required formatting. This is done as a list comprehension, could be done as inline code
import pandas as pd
import numpy as np
import plotly.express as px
df = pd.read_csv(
"https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv"
)
df["Date"] = pd.to_datetime(df["Date"])
# make data set more useful for demonstrating this plot
df.loc[df.sample((len(df)//8)*7).index, "direction"] = np.nan
px.line(df, x="Date", y="AAPL.Close").update_traces(line_color="red").add_traces(
[
px.scatter(
df.loc[df["direction"].eq(filter)], x="Date", y="AAPL.Close"
)
.update_traces(marker=fmt)
.data[0]
for filter, fmt in zip(
["Increasing", "Decreasing"],
[
{"color": "black", "symbol": "triangle-up", "size": 10},
{"color": "blue", "symbol": "triangle-down", "size": 10},
],
)
]
)

Change color of each bar in a grouped bar chart plotly to custom colors

I am trying to use custom hexa codes for each bar in a plotly chart but I am not able to work this out.
Could someone please help me.
Below is the code I a working with
#Defining Custom Colors
colours = {'Base_Models': '#0C3B5D',
'Standard_scaled_scores': '#3EC1CD',
'Min_Max_scaled_scores': '#EF3A4C',
'Scaling & feature selection_scores': '#FCB94D'}
import plotly.express as px
fig = px.bar(compareModels_aft_Cleansing, x="Base_Models", y=["Base_Models_Scores",
"Standard_scaled_scores", "Min_Max_scaled_scores",
"Scaling & feature selection_scores"],
title="Training Scores", barmode='group', text = 'value',
hover_name="Base_Models",
hover_data={'Base_Models':False}, # remove species from hover data
color = colours)
you have not provided sample data so I have synthesized
your colours map as I understand your dataframe is incorrect. You are plotting Base_Models_Scores as a bar not Base_Models, this is the x-axis
the parameter you require is color_discrete_map to achieve your requirement
import pandas as pd
import numpy as np
# Defining Custom Colors
colours = {
"Base_Models_Scores": "#0C3B5D",
"Standard_scaled_scores": "#3EC1CD",
"Min_Max_scaled_scores": "#EF3A4C",
"Scaling & feature selection_scores": "#FCB94D",
}
# generate sample data...
compareModels_aft_Cleansing = pd.DataFrame(
{
**{"Base_Models": colours.keys()},
**{
c: np.random.randint(1, 4, len(colours.keys()))
for c in colours.keys()
},
}
)
import plotly.express as px
fig = px.bar(
compareModels_aft_Cleansing,
x="Base_Models",
y=[
"Base_Models_Scores",
"Standard_scaled_scores",
"Min_Max_scaled_scores",
"Scaling & feature selection_scores",
],
title="Training Scores",
barmode="group",
text="value",
hover_name="Base_Models",
hover_data={"Base_Models": False}, # remove species from hover data
color_discrete_map=colours,
)
fig

Overlapping colorscales in plotly

I have plotted a figure with 2 subplots, each with different scales. Everything plots correctly, except the colorscales are both plotted on the right and completely overlap - they are are not readable. I cannot find out how to position/reposition the individual subplot scales. I have included my code below. Thanks.
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
df = pd.read_csv(entry)
custColorscale = [[0, 'green'], [0.5, 'red'], [1, 'rgb(50, 50, 50)']]
fig = make_subplots(
rows=1, cols=2, subplot_titles=('one', 'two'))
fig.add_trace(
go.Scatter(x=df['tO'],
y=df['t1'],
mode='markers',
marker=dict(colorscale=custColorscale,
cmin=0, cmax=2,
size=6, color=df['Var1'],
showscale=True),
text=df['Var2']),
1, 1)
fig.add_trace(
go.Scatter(x=df['tO'],
y=df['t1'],
mode='markers',
marker=dict(
size=6, color=df['Var2'],
showscale=True),
text=df['Var2']),
1, 2)
fig.update_layout(height=700, width=1900,
title='Raw data')
fig.update_layout(coloraxis=dict(
colorscale='Bluered_r'))
fig.write_html(fig, file='raw plots.html', auto_open=True)
Looking through the Plotly documentation you find this which provide some hints as to how to solve the problem. Scroll to the 'marker' attributes and you will find that it has sub-attribute called 'colorbar'. The colorbar in turn has multiple options that could help set the plot the way you want. Particularly you find the 'x', 'y' and 'len' attributes of the colorbar very useful. You can use them to position the scales.
This question is also related to this but for a contour plot - you are making a scatterplot which is why the scatterplot reference would be what one should search.
A minimal working example (MWE) is shown below but with a toy dataset.
## make necessary imports
import numpy as np
from plotly.subplots import make_subplots
import plotly.graph_objects as go
import pandas as pd
## make a fake dataset with pandas
d = {'t0': [i for i in np.arange(0.,10.,1.)], 't1': [i for i in
np.arange(10.,20.,1.)],'Var1': [i for i in np.arange(20.,30.,1.)],'Var2':
[i for i in np.arange(30.,40.,1.)] }
df = pd.DataFrame(data=d) #the dataset is made to mock the example code you provided
And for your plot you have the following :
# make subplots
custColorscale = [[0, 'green'], [0.5, 'red'], [1, 'rgb(50, 50, 50)']]
fig = make_subplots(
rows=1, cols=2, subplot_titles=('one', 'two'),horizontal_spacing = 0.4)
# plot 1
fig.add_trace(
go.Scatter(x=df['t0'],
y=df['t1'],
mode='markers',
marker=dict(colorscale=custColorscale,
cmin=0, cmax=2,
size=6, color=df['Var1'],
showscale=True,colorbar=dict(len=1.05, x=0.35
,y=0.49)), text=df['Var2']), 1, 1)
## plot 2
fig.add_trace(
go.Scatter(x=df['t0'],
y=df['t1'],
mode='markers',
marker=dict(
size=6, color=df['Var2'],
showscale=True,colorbar=dict(len=1.05, x=1.2 , y=0.49)),
text=df['Var2']),
1, 2 )
# show plots
fig.update_layout(height=500, width=700,
title='Raw data')
fig.update_layout(coloraxis=dict(
colorscale='Bluered_r'))
fig.show()
The only additions were:
The colorbar attribute of the marker.
The horizontal spacing to allow space for the first scale.
Feel free to play with these attributes.
I hope this helps!
Best regards.

Categories

Resources