how to control max length of colum names graph in plotly dash - python

i have a code like that
import plotly.express as px
df = px.data.gapminder().query("continent == 'Europe' and year == 2007 and pop > 2.e6")
fig = px.bar(df, y='pop', x='country', text='pop')
fig.update_traces(texttemplate='%{text:.2s}', textposition='outside')
fig.update_layout(uniformtext_minsize=8, uniformtext_mode='hide')
fig.show()
and it builds me this diagram
how to make max length on colums name?

I think there is a very similar question & answer here. Adapted to your case, you could chose to keep only the first n letters of the column name. It would look like the following:
import plotly.express as px
# Data
df = px.data.gapminder().query("continent == 'Europe' and year == 2007 and pop > 2.e6")
# Figure
fig = px.bar(df, y='pop', x='country', text='pop')
fig.update_traces(texttemplate='%{text:.2s}', textposition='outside')
fig.update_layout(uniformtext_minsize=8, uniformtext_mode='hide')
# The modification: overwrite tick labels
# Choose the number of letters to keep
n = 7
fig.update_layout(
xaxis = {
'tickmode': 'array',
'tickvals': df.country.unique().tolist(),
'ticktext': [i[:n] for i in df.country.unique().tolist()],
}
)
fig.show()
For n=7 it produces:

Related

How to highlight a single data point on a scatter plot using plotly express

In a scatter plot created using px.scatter, how do I mark one data point with a red star?
fig = px.scatter(df, x="sepal_width", y="sepal_length")
# Now set a single data point to color="red", symbol="star".
This isn't really highlighting an already existing data point within a trace you've already produced, but rather adding another one with a different visual appearance. But it does exactly what you're looking for:
fig.add_trace(go.Scatter(x=[3.5], y=[6.5], mode = 'markers',
marker_symbol = 'star',
marker_size = 15))
Plot:
Complete code:
import plotly.express as px
import pandas as pd
import plotly.graph_objects as go
df = px.data.iris() # iris is a pandas DataFrame
fig = px.scatter(df, x="sepal_width", y="sepal_length")
fig.add_trace(go.Scatter(x=[3.5], y=[6.5], mode = 'markers',
marker_symbol = 'star',
marker_size = 15))
fig.show()
This directly modifies the Scatter trace's Marker itself:
import plotly.express as px
df = px.data.iris()
fig = px.scatter(df, x="sepal_width", y="sepal_length")
trace = next(fig.select_traces())
# Modify kth point.
n = len(trace.x)
k = 136
color = [trace.marker.color] * n
color[k] = "red"
size = [8] * n
size[k] = 15
symbol = [trace.marker.symbol] * n
symbol[k] = "star"
# Update trace.
trace.marker.color = color
trace.marker.size = size
trace.marker.symbol = symbol
# Alternatively, call:
# fig.update_traces(marker=dict(color=color, size=size, symbol=symbol))
fig.show()

Adding counts to Plotly boxplots

I have a relatively simple issue, but cannot find any answer online that addresses it. Starting from a simple boxplot:
import plotly.express as px
df = px.data.iris()
fig = px.box(
df, x='species', y='sepal_length'
)
val_counts = df['species'].value_counts()
I would now like to add val_counts (in this dataset, 50 for each species) to the plots, preferably on either of the following places:
On top of the median line
On top of the max/min line
Inside the hoverbox
How can I achieve this?
The snippet below will set count = 50 for all unique values of df['species'] on top of the max line using fig.add_annotation like this:
for s in df.species.unique():
fig.add_annotation(x=s,
y = df[df['species']==s]['sepal_length'].max(),
text = str(len(df[df['species']==s]['species'])),
yshift = 10,
showarrow = False
)
Plot:
Complete code:
import plotly.express as px
df = px.data.iris()
fig = px.box(
df, x='species', y='sepal_length'
)
for s in df.species.unique():
fig.add_annotation(x=s,
y = df[df['species']==s]['sepal_length'].max(),
text = str(len(df[df['species']==s]['species'])),
yshift = 10,
showarrow = False
)
f = fig.full_figure_for_development(warn=False)
fig.show()
Using same approach that I presented in this answer: Change Plotly Boxplot Hover Data
calculate all the measures a box plot calculates plus the additional measure you want count
overlay bar traces over box plot traces so hover has all measures required
import plotly.express as px
df = px.data.iris()
# summarize data as per same dimensions as boxplot
df2 = df.groupby("species").agg(
**{
m
if isinstance(m, str)
else m[0]: ("sepal_length", m if isinstance(m, str) else m[1])
for m in [
"max",
("q75", lambda s: s.quantile(0.75)),
"median",
("q25", lambda s: s.quantile(0.25)),
"min",
"count",
]
}
).reset_index().assign(y=lambda d: d["max"] - d["min"])
# overlay bar over boxplot
px.bar(
df2,
x="species",
y="y",
base="min",
hover_data={c:not c in ["y","species"] for c in df2.columns},
hover_name="species",
).update_traces(opacity=0.1).add_traces(px.box(df, x="species", y="sepal_length").data)

How to create secondary y-axes from a plotly express facetted figure?

I would like to modify a facetted plotly.express figure so that each trace has its own secondary y-axis. I don't want to re-create the figure from scratch using the standard Plotly-python api if possible. See exmaple below.
import plotly.express as px
input_df = px.data.tips()
fig = px.scatter(input_df,
x = 'total_bill',
y = 'tip',
color = 'day',
facet_row = 'smoker',
facet_col = 'sex',
)
fig.layout.width = 800
fig.show()
I would like to convert the above so each trace (or color) has its own secondary y-axis. So in this case, I would like 3 additional y-axes for each facet. This is my attempt but it doesn't work. There must be a better way. I would appreciate any ideas.
import plotly.graph_objects as go
yaxes = []
for trace in fig.data:
yaxisLabel = trace['yaxis']
if trace['yaxis'] in yaxes:
if yaxisLabel == 'y':
axisnumber = 0
else:
axisnumber = int(trace['yaxis'][1:])
newAxis_num = axisnumber + 100 * yaxes.count(yaxisLabel)
exec(f"fig.layout.update(yaxis{newAxis_num} = go.layout.YAxis(overlaying='y', side='right'))")
trace.update({'yaxis': f'y{newAxis_num}'})
yaxes.append(yaxisLabel)

Add dropdown menu to plotly express treemap

I am currently trying to add a dropdown menu to my treemap plot
The code I am using :
import pandas as pd
import plotly.express as px
fig = px.treemap(df,
path=['RuleName','RuleNumber','ParaInvolved',"CreationP","MAjP"],
color='Somme',
hover_data=["RuleDecision","RuleMAJ"],
color_continuous_scale='RdBu')
fig.show()
The problem I am facing is that in my column "RuleName" I have 151 different values (but 1300 rows in total), that's why I'm trying to add a button allowing myself to chose for what RuleName value I want to plot my treemap. For now I am using a barbaric method consisting in filtering my dataframe by each RuleName value, which lead me to get 151 different treemap. I don't find any solution on that website or any other.
Thanks for your help
Here I'm basically using the same logic from this answer but I use px.treemap(...).data[0] to produce the traces instead of go.
import plotly.express as px
import plotly.graph_objects as go
df = px.data.tips()
# We have a list for every day
# In your case will be gropuby('RuleName')
# here for every element d
# d[0] is the name(key) and d[1] is the dataframe
dfs = list(df.groupby("day"))
first_title = dfs[0][0]
traces = []
buttons = []
for i,d in enumerate(dfs):
visible = [False] * len(dfs)
visible[i] = True
name = d[0]
traces.append(
px.treemap(d[1],
path=['day', 'time', 'sex'],
values='total_bill').update_traces(visible=True if i==0 else False).data[0]
)
buttons.append(dict(label=name,
method="update",
args=[{"visible":visible},
{"title":f"{name}"}]))
updatemenus = [{'active':0, "buttons":buttons}]
fig = go.Figure(data=traces,
layout=dict(updatemenus=updatemenus))
fig.update_layout(title=first_title, title_x=0.5)
fig.show()

Plotly: How to add elements to hover_data using plotly.express piechart?

I am playing with examples from plotly.express piechart help page and trying to add an extra element iso_num to the hover_data property (iso_num is an int64 column in the gapminder dataframe)
import plotly.express as px
df = px.data.gapminder().query("year == 2007").query("continent == 'Americas'")
fig = px.pie(df, values='pop', names='country',
title='Population of American continent',
hover_data=['lifeExp','iso_num'], labels={'lifeExp':'life expectancy','iso_num':'iso num'
})
fig.update_traces(textposition='inside', textinfo='percent+label')
fig.show()
Hovering over the slice of the pie chart then gives this:
where iso num value is %{customdata[1]} instead of the numeric value from the column.
What am I missing?
Thanks!
I found a way to do it with Plotly Express Pie chart as well. You can use update_traces to define hover_template. It seems there is an issue with splitting on multiple values for hover_data/custom_data and all values are present at 0 index only i.e. both values are at customdata[0].
import plotly.express as px
df = px.data.gapminder().query("year == 2007").query("continent == 'Americas'")
fig = px.pie(df, values='pop', names='country',
title='Population of American continent',
custom_data=['lifeExp','iso_num'], labels={'lifeExp':'life expectancy','iso_num':'iso num'
})
fig.update_traces(textposition='inside', textinfo='percent+label',\
hovertemplate = "Country:%{label}: <br>Population: %{value} </br>(life expentancy, iso num) : %{customdata}"
)
fig.show()
On hover:
This seems to be a relic from back when it was stated that
Oh pie hover is a big mess
Which since seems to be have been resolved. But perhaps not for px.pie()?
I've tried numerous approaches, but I'm only able to get the customdata + hovertemplate approach to work for go.Pie and not for px.Pie. Here's a demonstration on how assigning values to customdata will make any variable otherwise not assigned to go.Pie() available for a custom hovertamplate:
Plot:
Code:
import plotly.graph_objects as go
import plotly.express as px
df = px.data.gapminder().query("year == 2007").query("continent == 'Americas'")
fig = go.Figure(go.Pie(
name = "",
values = df['pop'],
labels = df['country'],
customdata=df['iso_num'],
hovertemplate = "Country:%{label}: <br>Population: %{value} </br> iso num:%{customdata}"
))
fig.show()

Categories