Philippe Haumesser
Philippe Haumesser

Reputation: 647

Plotly chart percentage with smileys

I would like o add a plot figure based on smileys like this one: dat will come from a dataframe pandas : dataframe.value_counts(normalize=True)

enter image description here

Can some one give me some clues.

Upvotes: 1

Views: 1105

Answers (1)

Rob Raymond
Rob Raymond

Reputation: 31166

  • use colorscale in normal way for a heatmap
  • use anotation_text to assign an emoji to a value
import plotly.figure_factory as ff
import plotly.graph_objects as go
import pandas as pd
import numpy as np


df = pd.DataFrame([[j*10+i for i in range(10)] for j in range(10)])

e=["😃","🙂","😐","☚ī¸"]

fig = go.Figure(ff.create_annotated_heatmap(
    z=df.values, colorscale="rdylgn", reversescale=False,
    annotation_text=np.select([df.values>75, df.values>50, df.values>25, df.values>=0], e),
))


fig.update_annotations(font_size=25)
# allows emoji to use background color
fig.update_annotations(opacity=0.7) 

enter image description here

update coloured emoji

  • fundamentally you need emojicons that can accept colour styling
  • for this I switched to Font Awesome. This then also requires switching to dash, plotly's cousin so that external CSS can be used (to use FA)
  • then build a dash HTML table applying styling logic for picking emoticon and colour
from jupyter_dash import JupyterDash
import dash_html_components as html
import pandas as pd
import branca.colormap

# Load Data
df = pd.DataFrame([[j*10+i for i in range(10)] for j in range(10)])

external_stylesheets = [{
    'href': 'https://use.fontawesome.com/releases/v5.8.1/css/all.css',
    'rel': 'stylesheet', 'crossorigin': 'anonymous',
    'integrity': 'sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf',
    }]

# possibly could use a a different library for this - simple way to map a value to a colormap
cm = branca.colormap.LinearColormap(["red","yellow","green"], vmin=0, vmax=100, caption=None)

def mysmiley(v):
    sm = ["far fa-grin", "far fa-smile", "far fa-meh", "far fa-frown"]
    return html.Span(className=sm[3-(v//25)], style={"color":cm(v),"font-size": "2em"})

# Build App
app = JupyterDash(__name__, external_stylesheets=external_stylesheets)
app.layout = html.Div([
    html.Table([html.Tr([html.Td(mysmiley(c)) for c in r]) for r in df.values])
])

# Run app and display result inline in the notebook
app.run_server(mode='inline')

enter image description here

Upvotes: 3

Related Questions