Plotly: How to highlight certain xticks?

Viewed 728
class parser(object):
    """docstring for parser"""
    def __init__(self, path):
        self.encodeCSV = pd.read_csv(path, ',')
        self.metrics = {
                         "train_rmse" : "RMSE_Tr",
                         "validation_rmse" : "RMSE_V",
                         "train_90_quantile" : "90QT_Tr",
                         "validation_90_quantile" : "90QT_V"
                       }

    def generate_img(self):
        fig = go.Figure({
                         'layout' : {'title': {'text': 'Combination Model'},
                                     'xaxis': {'title': {'text': 'Models'}},
                                     'yaxis': {'title': {'text': 'KPI Values'}}}
                            
                        })

        for metric in self.metrics:
            fig.add_trace(go.Scatter(x=self.encodeCSV['names'],
                                     y=self.encodeCSV[metric],
                                     mode='lines+markers',
                                     name=self.metrics[metric]))
        return fig

I have generated a figure to analyze models' performance by plotly.

Here is a sample enter image description here

Now I have to highlight a model with best result and one straightforward way is just change the color of the xtick of the model (change the color of the circled xtick as following) enter image description here

Is there a simple way to do that?

1 Answers

There are easier ways than adding more axes as suggested in the comments. Plotly recognizes html formatting, so you can easily format only one of the values that goes into the x argument in go.Scatter() like '<em>'+x+'</em>' to get this:

Plot 1:

enter image description here

Admittedly, the C does not stand out that much, so what I like to do instead of adding separate axes, is adding separate traces to make certain points on the figure stand out. Here I've combined an extra trace with som html formatting as well:

Plot 2:

enter image description here

What I like best about this approach is that it adds some extra value through increasing interactivity when you can opt to show or hide the highlighted points by clicking on the names in the legend. I hope you'll find this useful. Don't hesitate to let me know if something is unclear.

Complete code:

import plotly.graph_objects as go
import pandas as pd
import numpy as np

# data
df = pd.DataFrame({'x': list('ABCDE'),
                   'y': [2,4,1,3,5]})

#df['y_min'] = np.where(df['y']==df['y'].min(), df['y'], np.nan)
# series with formatted x values using a list comprehension
# (further improvements are welcomed!)
#df['x_txt'] = ['<i>'+x+'</i>' if np.isnan(df['y_min'].iloc[i]) else '<b>'+x+'</b>' for i, x in enumerate(df['x'])]

# Edited -->
# Create list containing x-labels.
ymin = df['y'].argmin()
xlabels = [f"<i>{x}</i>" for x in df['x']]
xlabels[ymin] = xlabels[ymin].replace('i', 'b')

# Create array of y values.
y = np.full(df['y'].size, np.nan)
y[ymin] = df['y'].min()
# <--

# plotly
fig = go.Figure()

# add highlighted point first to appear in the back
fig.add_trace(go.Scatter(x = xlabels, y = y,        # Edited
                             mode = 'markers',
                             marker = dict(color='red', size = 12),
                             name = 'best'))

# add the main values to the figure
fig.add_trace(go.Scatter(x = xlabels, y = df['y'],   # Edited
                             mode = 'lines',
                             marker =dict(color='blue'),
                             name = 'other values'))

fig.show()
Related