I am trying to incorporate spaCy
's NER pre-trained model into my Dash
Dashboard. I know Dash
currently does not have the ability to render raw html so I am looking for a solution. I have search the online extensively without finding a solution.
Currently, I have a dashboard that looks like this:
Where I would like the SpaCy
's NER output to show underneath if possible. As an example please see the image below:
If anyone has managed to find a solution that works with Dash
, please let me know. If it isn't possible then it isn't the end of the world. I know it can be done in Flask
albeit it is harder to code in HTML!
Many thanks!
it's not possible to render it in one line through displacy. However, you should be able to abstract the html through python functions and manually render the results. Here's an example app:
import dash
import dash_html_components as html
import spacy
from spacy.displacy.render import DEFAULT_LABEL_COLORS
# Initialize the application
app = dash.Dash(__name__)
def entname(name):
return html.Span(name, style={
"font-size": "0.8em",
"font-weight": "bold",
"line-height": "1",
"border-radius": "0.35em",
"text-transform": "uppercase",
"vertical-align": "middle",
"margin-left": "0.5rem"
})
def entbox(children, color):
return html.Mark(children, style={
"background": color,
"padding": "0.45em 0.6em",
"margin": "0 0.25em",
"line-height": "1",
"border-radius": "0.35em",
})
def entity(children, name):
if type(children) is str:
children = [children]
children.append(entname(name))
color = DEFAULT_LABEL_COLORS[name]
return entbox(children, color)
def render(doc):
children = []
last_idx = 0
for ent in doc.ents:
children.append(doc.text[last_idx:ent.start_char])
children.append(
entity(doc.text[ent.start_char:ent.end_char], ent.label_))
last_idx = ent.end_char
children.append(doc.text[last_idx:])
return children
text = "When Sebastian Thrun started working on self-driving cars at Google in 2007, few people outside of the company took him seriously."
nlp = spacy.load("en_core_web_sm")
doc = nlp(text)
print("Entities:", doc.ents)
# define de app
app.layout = html.Div(
children=render(doc)
)
# Run the app
if __name__ == "__main__":
app.run_server(debug=True)
This produces the following result:
In the example above, the entname
and entbox
functions will respectively generate an html.Span
and html.Mark
with the style copied from the output html in displacy
. Then, the function entity
abstracts the previous two functions to easily generate an entity box. Finally, the render
function will take spacy's Doc
object and convert it into a list of Dash html
components, which can be used inside the Dash layout.