Different colour for each wrapped text

I have wrapped text based on \n and have displayed multiple text in one cell like this:

Now I want to have diferent colour for each line . I tried to do based on pattern matching but i Think it is not possible.

sample dictionary for diagram above:

image

my code:

from dash import Dash, dash_table
import pandas as pd
import numpy as np
import pandas as pd
from dash import Dash, dcc, html, Input, Output

from dash import Dash, html
from dash import Dash, dash_table
import pandas as pd
import numpy as np
import dash
import dash_table
import pandas as pd
import re

df = pd.read_csv(
    r'C:\Users\hp\Desktop\plotly_dash\Confidential_company\Ladder_confidential_company.csv')
mapping_material=pd.read_excel(r"C:\Users\hp\Desktop\plotly_dash\Confidential_company\Material_products_mapping.xlsx")
df=pd.merge(df,mapping_material,on="Material",how="left")
df["Date_pred"] = pd.to_datetime(df["TYear"].astype(str)+"-" +
                                 df["TMonth"].astype(str), format="%Y-%m")

df["Date_of_pred"] = pd.to_datetime(df["YearOfPrediction"].astype(str)+"-" +
                                    df["MonthOfPrediction"].astype(str),
                                    format="%Y-%m")


df.drop(["TYear", "TMonth", "YearOfPrediction",
        "MonthOfPrediction"], 1, inplace=True)

df["Date_of_pred"] = df["Date_of_pred"].astype(str)
df["Date_pred"] = df["Date_pred"].astype(str)

df = df.fillna(0)


df_copy = df[df.Product=='DF']

projected_copy = pd.pivot_table(df_copy, index="Date_of_pred",
                                values="Projected Sales",
                                columns="Date_pred")
projected_copy.columns.name=None
projected_copy=projected_copy.reset_index().fillna('')

actual_sales_copy = pd.pivot_table(df_copy, index="Date_of_pred",
                                   values="Actual Sales",
                                   columns="Date_pred")
actual_sales_copy.columns.name=None
actual_sales_copy=actual_sales_copy.reset_index().fillna('') 


dawlance_pred_copy = pd.pivot_table(df_copy, index="Date_of_pred",
                                    values="Dawlance Prediction",
                                    columns="Date_pred")
dawlance_pred_copy.columns.name=None
dawlance_pred_copy=dawlance_pred_copy.reset_index().fillna('') 


new_file = projected_copy.astype(str).set_index("Date_of_pred")+"\n"+actual_sales_copy.astype(str).set_index("Date_of_pred")

new_file = new_file.astype(str)+"\n"+dawlance_pred_copy.astype(str).set_index("Date_of_pred")

new_file=new_file.reset_index()

app = dash.Dash(__name__)




app.layout = html.Div([
    dash_table.DataTable(
        id="table",
        columns=[{"name": i, "id": i} for i in new_file.columns],
        data=new_file.to_dict("records"),
        style_cell={"whiteSpace": "pre-line"},
    #     style_cell_conditional=[
    # {
    #     'if': {'column_id': 'Region'},
    #     'textAlign': 'left'
    # }
# ]
    ),
    

    dcc.RadioItems(
        list(df["Product"].unique()),
        'DF',
        id='Product-radio',
    ),
])

@app.callback(
    Output('table', 'data'),
    Input('Product-radio', 'value'))
def update_figure(product):
    df_copy = df[df.Product==product]
    
    projected_copy = pd.pivot_table(df_copy, index="Date_of_pred",
                                    values="Projected Sales",
                                    columns="Date_pred")
    projected_copy.columns.name=None
    projected_copy=projected_copy.reset_index().fillna('')

    actual_sales_copy = pd.pivot_table(df_copy, index="Date_of_pred",
                                       values="Actual Sales",
                                       columns="Date_pred")
    actual_sales_copy.columns.name=None
    actual_sales_copy=actual_sales_copy.reset_index().fillna('') 


    dawlance_pred_copy = pd.pivot_table(df_copy, index="Date_of_pred",
                                        values="Dawlance Prediction",
                                        columns="Date_pred")
    dawlance_pred_copy.columns.name=None
    dawlance_pred_copy=dawlance_pred_copy.reset_index().fillna('') 


    new_file = projected_copy.astype(str).set_index("Date_of_pred")+"\n"+actual_sales_copy.astype(str).set_index("Date_of_pred")

    new_file = new_file.astype(str)+"\n"+dawlance_pred_copy.astype(str).set_index("Date_of_pred")

    new_file=new_file.reset_index()
    

    return new_file.to_dict("records")
    

    

if __name__ == "__main__":
    app.run_server(debug=False)

Hi @abubakar624
:wave: Welcome to the Dash Community.

If I understand correctly, you’re trying to have each line of text inside each row have a different color? Or are you trying to have each row a different color?

1 Like

Thank You.Yes , i want to have each line of text inside each row having a different colour. I want some thing like this:

Actually I was previously using tableau for this purpose, but now Our organization is considering shifting to Dash-plotly.In tableau you could have different colours by assigning different colours to each text box. Thanks in advance

hi @abubakar624
I am not sure this is possible. As you can see from the code below, you can highlight rows, based on cell value, but I don’t think you can highlight specific line inside each cell. Docs here.

from dash import Dash, dash_table
import pandas as pd
from collections import OrderedDict

data = OrderedDict(
    [
        ("Date", ["2015-01-01", "2015-10-24", "2016-05-10", "2017-01-10", "2018-05-10", "2018-08-15"]),
        ("Region", ["Montreal\nMontreal2", "Toronto", "New York City", "Miami", "San Francisco", "London"]),
        ("Temperature", [1, -20, 3.512, 4, 10423, -441.2]),
        ("Humidity", [10, 20, 30, 40, 50, 60]),
        ("Pressure", [2, 10924, 3912, -10, 3591.2, 15]),
    ]
)

df = pd.DataFrame(data)

app = Dash(__name__)

app.layout = dash_table.DataTable(
    data=df.to_dict('records'),
    columns=[
        {'name': i, 'id': i} for i in df.columns
    ],
    style_cell={'whiteSpace': 'pre-line'},
    style_data_conditional=[
        {
            'if': {
                'filter_query': '{Region} = "Toronto"'
            },
            'color': 'red'
        }
    ]
)

if __name__ == '__main__':
    app.run_server(debug=True)

Thank you, @adamschroeder . I Think then I would have to try another strategy for achieving this. I think this is really useful thing in many circumstances. Ladder is often used in many organizations and here it becomes necessary to have different colours for each line(for example actual values in blue and predicted values in green). I think there should be some way in datatable(plotly) to access individual string and highlight specific string part based on condition .For example through indexing or another way.

@abubakar624

If you do a little more data wrangling to put each value in a separate row, then using conditional formatting as Adam recommended would work.

Alternately, you can format the cells with html. Here’s an example:

image

from dash import Dash, dash_table
import pandas as pd

data = dict(
    [
        ("Date",["2015-01-01", "2015-10-24","2016-05-10"]),
        ("values", ["1\n1.2\n1.3", "2\n2.2\n2.3", "3\n3.2\n3.3"]),
    ]
)


df = pd.DataFrame(data)


def format_cell(cell):
    values = cell.split("\n")
    colors = ["blue", "red", "green"]
    styled = [f"<div style='color: {c}'>{v}</div>" for v, c in zip(values, colors)]
    return "".join(styled)


df["values"] = df["values"].apply(format_cell)


app = Dash(__name__)

app.layout = dash_table.DataTable(
    data=df.to_dict("records"),
    columns=[{"name": i, "id": i, "presentation": "markdown"} for i in df.columns],
    markdown_options={"html": True},
)

if __name__ == "__main__":
    app.run_server(debug=True)
4 Likes

@AnnMarieW thank you, it really solved my problem. I have just made rough chart and it is really working. I did not know about formatting through html in this way. This is really a powerful feature. Thank you again for a prompt and helpful response. I believe that this feature should be in documentation in early pages. It really helps integrating pandas dataframe with plotly in a most comprehensive manner.

2 Likes

Beautiful solution. Thank you for sharing, @AnnMarieW :muscle:

1 Like