Add hyperlink to Python Plotly Sunburst diagram - javascript

If possible, I need to add hyperlinks to a Plotly Sunburst chart so that a user can click and go to a webpage with more information.
Sunburst chart showing where hyperlinks are needed
I've tried organizing the data two different ways
Here's the data in coffeeURL.csv:
ids,labels,parents
Enzymatic-Flowery,Flowery,
Enzymatic-Fruity,Fruity,
Enzymatic-Herby,Herby,
<a href=Flower-Floral.html>Flowery-Floral</a>,Floral,Enzymatic-Flowery
<a href=Flower-Fragrant.html>Flowery-Fragrant</a>,Fragrant,Enzymatic-Flowery
<a href=Fruity-Citrus.html>Fruity-Citrus</a>,Citrus,Enzymatic-Fruity
<a href=Fruity-Berry-like.html>Fruity-Berry-like</a>,Berry-like,Enzymatic-Fruity
<a href=Herby-Alliaceous.html>Herby-Alliaceous</a>,Alliaceous,Enzymatic-Herby
<a href=Herby-Leguminous.html>Herby-Leguminous</a>,Leguminous,Enzymatic-Herby
Here's the script:
import plotly.graph_objects as go
import pandas as pd
df = pd.read_csv('coffeeURL.csv')
fig = go.Figure()
fig.add_trace(go.Sunburst(
ids=df.ids,
labels=df.labels,
parents=df.parents,
domain=dict(column=1),
maxdepth=2,
insidetextorientation='radial'
))
fig.update_layout(
margin = dict(t=10, l=10, r=10, b=10)
)
fig.show()

you can achieve this is you use dash and a callback
your URLs are not accessible to me so have used results of a Google search with results going into an Iframe
import pandas as pd
import io
import plotly.graph_objects as go
from jupyter_dash import JupyterDash
from dash import html, dcc
from dash.dependencies import Input, Output
from dash.exceptions import PreventUpdate
# Build App
app = JupyterDash(__name__)
df = pd.read_csv(io.StringIO("""ids,labels,parents
Enzymatic-Flowery,Flowery,
Enzymatic-Fruity,Fruity,
Enzymatic-Herby,Herby,
<a href=Flower-Floral.html>Flowery-Floral</a>,Floral,Enzymatic-Flowery
<a href=Flower-Fragrant.html>Flowery-Fragrant</a>,Fragrant,Enzymatic-Flowery
<a href=Fruity-Citrus.html>Fruity-Citrus</a>,Citrus,Enzymatic-Fruity
<a href=Fruity-Berry-like.html>Fruity-Berry-like</a>,Berry-like,Enzymatic-Fruity
<a href=Herby-Alliaceous.html>Herby-Alliaceous</a>,Alliaceous,Enzymatic-Herby
<a href=Herby-Leguminous.html>Herby-Leguminous</a>,Leguminous,Enzymatic-Herby"""))
fig = go.Figure()
fig.add_trace(go.Sunburst(
ids=df.ids,
labels=df.labels,
parents=df.parents,
domain=dict(column=1),
maxdepth=2,
insidetextorientation='radial'
))
fig.update_layout(
margin = dict(t=10, l=10, r=10, b=10)
)
app.layout = html.Div(
[
dcc.Graph(
id="figure",
figure=fig,
),
html.Iframe(
id="details",
src="https://www.google.com/search?igu=1&ei=&q=flowers",
style={"height": "1067px", "width": "100%"},
),
]
)
#app.callback(Output("details", "src"), [Input("figure", "clickData")])
def clickPoint(clickData):
if clickData:
try:
clicked_id = clickData["points"][0]["id"]
clicked_id = clicked_id.split(">")[1].split("<")[0]
return f"https://www.google.com/search?igu=1&ei=&q={clicked_id}"
except IndexError:
raise PreventUpdate
else:
raise PreventUpdate
app.run_server(mode="inline")

Related

Displaying D3.js Chart with Django Backend

I am learning to build dashboard using Django as backend and D3.js for visualization.
Following is my index.html:
{% load static %}
<html>
<script src="https://d3js.org/d3.v7.min.js"></script>
<body>
<h1> Hello! </h1>
<script src={% static "js\linechart.js" %}>
var data = {{ AAPL|safe }};
var chart = LineChart(data, {
x: d => d.date,
y: d => d.close,
yLabel: "↑ Daily close ($)",
width,
height: 500,
color: "steelblue"
})
</script>
</body>
</html>
Data AAPl is extracted from database and the views.py is as follows:
from django.shortcuts import render
from django.http import HttpResponse
from cnxn import mysql_access
import pandas as pd
# Create your views here.
def homepage(request):
sql = ''' select Date, Close from tbl_historical_prices where ticker = 'AAPL' '''
cnxn = mysql_access()
conn = cnxn.connect()
df = pd.read_sql(sql, con=conn)
context = {'AAPL':df.to_json()}
return render(request, 'index.html', context=context)
Function line chart can be viewed here which is being used in js\linechat.js in index.html file.
I can see the Hello! being displayed on the page but can't see the line chart. I am unable to debug the problem. No errors found in console tab either.
How can I display the line plot?
I've added the current page display in attached image.
Close off your script with a src and start a new script tag. The presence of src precludes internal code.
<script src={% static "js\linechart.js" %}></script>
<script>
...

update the return data automatically in flask templates

I am working on Yolov3, OpenCV,python and Flask. Here, I explain the details of usage for each item.
Yolov3 - To detect and recognize object in video input
Opencv - To capture images of detected object in video input.
Flask - As a web server since it's support python language.
My objective
To develop application which able to captured the image of the object and update in the flask web directly or real-time
For your information, currently my system able to capture image and save in one folder which name as images by using OpenCv and python. you can refer the code below.
opencv and python code to capture image of object detected
for i in range(len(boxes)):
if i in indexes:
x,y,w,h = boxes[i]
label = str(LABELS[class_ids[i]])
confidence= confidences[i]
color = colors[class_ids[i]]
crop_img = image[y:y + h, x:x + w]
imagesPath = "images/file_%d.jpg"%self.d
cv2.imwrite(imagesPath, crop_img)
self.d+=1
cv2.rectangle(image,(x,y),(x+w,y+h),color,2)
cv2.putText(image,label+" "+str(round(confidence,2)),(x,y+30),font,1,(255,255,255),2)
When the images successfully save in images folder. I convert all the images in to base64 and return as json in flask. Here I attach the python code in flask.
Covert image to base64 and render in html templates
#app.route("/images")
def get_images():
directory = os.listdir('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images')
os.chdir('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images')
image_list= list()
for file in directory:
data = dict()
base = os.path.basename(file)
data["label"] = base
open_file = open(file,'rb')
image_read = open_file.read()
image_64_encode = base64.encodebytes(image_read)
data["data"] = image_64_encode.decode('ascii')
image_list.append(data)
final_data = {'files':image_list}
return render_template('images.html', final_data=final_data)
images.html
<!DOCTYPE html>
<html>
<head>
<!DOCTYPE html>
<html lang="en">
<head>
<title>yolo</title>
</head>
<body>
<h1 class="logo">Results</h1>
<ul>
{% for data in final_data.files %}
<li>{{data.label}}</li>
<img alt="embedded" src="data:image/jpg;base64,{{data.data}}"/>
{% endfor %}
</ul>
</body>
</html>
Problem and question
I have two major problem here.
1) When i run my application, my application captured the images welly. But it's automatically stop when image.html page is open to display the picture. Why it's happen and how to solve this?
2) If the application able to capture image even i open the image.html page. What should i do to update my web directly or real-time?
Here I attach the full code. Because I have been works for many weeks but still not found the solution. Hope someone can helps. Let's me know if u need more information
code
App.py
from flask import Flask, render_template, Response,jsonify
from camera import VideoCamera
import numpy as np
import os
import time
import detect as dt
from PIL import Image
import cv2
import base64
import json
from pprint import pprint
app = Flask(__name__)
def success_handle(output, status=200, mimetype='application/json'):
return Response(output, status=status, mimetype=mimetype)
#app.route("/images")
def get_images():
directory = os.listdir('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images')
os.chdir('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images')
flist = list()
for file in directory:
data = dict()
base = os.path.basename(file)
data["label"] = base
open_file = open(file,'rb')
image_read = open_file.read()
image_64_encode = base64.encodebytes(image_read)
data["data"] = image_64_encode.decode('ascii')
flist.append(data)
final_data = {'files':flist}
return render_template('images.html', final_data=final_data)
#app.route('/')
def index():
return render_template('index.html')
def gen(camera):
frame_id = 0
while True:
frame = camera.get_frame()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
#app.route('/video_feed')
def video_feed():
return Response(gen(VideoCamera()),
mimetype='multipart/x-mixed-replace; boundary=frame')
if __name__ == '__main__':
app.run(host='0.0.0.0', debug=True)
camera.py
import cv2
import time
import os
import numpy as np
font = cv2.FONT_HERSHEY_PLAIN
starting_time= time.time()
frame_id = 0
count = 0
d = 0
labelsPath = os.path.sep.join(["yolo-coco", "coco.names"])
weightsPath = os.path.sep.join(["yolo-coco", "yolov3.weights"])
configPath = os.path.sep.join(["yolo-coco", "yolov3.cfg"])
#imagesPath = 'C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images/file_%d.jpg"%d'
labelsPath = os.path.sep.join(["yolo-coco", "coco.names"])
VideoPath = os.path.sep.join(["videos", "highway.mp4"])
LABELS = open(labelsPath).read().strip().split("\n")
net = cv2.dnn.readNet(configPath, weightsPath)
layer_names = net.getLayerNames()
outputlayers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
colors= np.random.uniform(0,255,size=(len(LABELS),3))
class VideoCamera(object):
def __init__(self):
# Using OpenCV to capture from device 0. If you have trouble capturing
# from a webcam, comment the line below out and use a video file
# instead.
self.video = cv2.VideoCapture(VideoPath)
self.frame_id = 0
self.d = 0
# If you decide to use video.mp4, you must have this file in the folder
# as the main.py.
# self.video = cv2.VideoCapture('video.mp4')
def __del__(self):
self.video.release()
def get_frame(self):
success, image = self.video.read()
# We are using Motion JPEG, but OpenCV defaults to capture raw images,
# so we must encode it into JPEG in order to correctly display the
# video stream.
self.frame_id+=1
#print(frame_id)
height,width,channels = image.shape
#print (frame.shape)
#detecting objects
blob = cv2.dnn.blobFromImage(image,0.00392,(320,320),(0,0,0),True,crop=False) #reduce 416 to 320
net.setInput(blob)
outs = net.forward(outputlayers)
#print(outs)
print(outs[1])
#Showing info on screen/ get confidence score of algorithm in detecting an object in blob
class_ids=[]
confidences=[]
boxes=[]
for out in outs:
#print(out)
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
print(confidence)
if confidence > 0.8:
#object detected
center_x= int(detection[0]*width)
center_y= int(detection[1]*height)
w = int(detection[2]*width)
h = int(detection[3]*height)
#cv2.circle(img,(center_x,center_y),10,(0,255,0),2)
#rectangle co-ordinaters
x=int(center_x - w/2)
y=int(center_y - h/2)
#cv2.rectangle(img,(x,y),(x+w,y+h),(0,255,0),2)
boxes.append([x,y,w,h]) #put all rectangle areas
confidences.append(float(confidence)) #how confidence was that object detected and show that percentage
class_ids.append(class_id) #name of the object tha was detected
indexes = cv2.dnn.NMSBoxes(boxes,confidences,0.4,0.6)
# result = open('C:/Users/HP/Miniconda3/envs/count_vechicle/coding/images/frame%04d.txt'%(count), 'w')
for i in range(len(boxes)):
if i in indexes:
x,y,w,h = boxes[i]
label = str(LABELS[class_ids[i]])
# cv2.imwrite(label, crop_img)
confidence= confidences[i]
color = colors[class_ids[i]]
crop_img = image[y:y + h, x:x + w]
imagesPath = "images/file_%d.jpg"%self.d
cv2.imwrite(imagesPath, crop_img)
self.d+=1
cv2.rectangle(image,(x,y),(x+w,y+h),color,2)
cv2.putText(image,label+" "+str(round(confidence,2)),(x,y+30),font,1,(255,255,255),2)
elapsed_time = time.time() - starting_time
fps=frame_id/elapsed_time
cv2.putText(image,"FPS:"+str(round(fps,2)),(10,50),font,2,(0,0,0),1)
# cv2.imshow("Image",image)
# key = cv2.waitKey(1) #wait 1ms the loop will start again and we will process the next frame
# if key == 27: #esc key stops the process
# break;
ret, jpeg = cv2.imencode('.jpg', image)
return jpeg.tobytes()
index.html
<html>
<head>
<title>Object Detection</title>
</head>
<body>
<h1>Video Streaming Demonstration</h1>
<img src="{{ url_for('video_feed') }}">
</body>
</html>
images.html
<!DOCTYPE html>
<html>
<head>
<!DOCTYPE html>
<html lang="en">
<head>
<title>yolo</title>
</head>
<body>
<h1 class="logo">Results</h1>
<ul>
{% for data in final_data.files %}
<li>{{data.label}}</li>
<img alt="embedded" src="data:image/jpg;base64,{{data.data}}"/>
{% endfor %}
</ul>
</body>
</html>

getting the status of arduino digital pins in webpage

I want to read the status of my digital pins of arduino and want to display it
in web page. For web programming i am using Flask. I tried this code but its not working. from arduino side I am reading the values of 6 digital pins in the form of 1 and 0. How i can do this? Any help would be appreciated.
<!doctype html>
<html>
<head>
</head>
<body>
<h1 style="font-size:30px;font-family:verdana;"><b>STATUS READ </h1><br><br>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<p id="#status1"></p>
<p id="#status2"></p>
<p id="#status3"></p>
<p id="#status4"></p>
<p id="#status5"></p>
<p id="#status6"></p>
<script type=text/javascript>
function updatevalues() {
$SCRIPT_ROOT = {{ request.script_root|tojson|safe }};
$.getJSON($SCRIPT_ROOT+"/a",
function(data) {
$("#status1").text(data.m+" %")
$("#status2").text(data.n+" %")
$("#status3").text(data.o+" %")
$("#status4").text(data.p+" %")
$("#status5").text(data.q+" %")
$("#status6").text(data.r+" %")
});
}
</script>
</body>
</html>
Python code:
from flask import Flask, render_template,request,redirect, url_for,jsonify,flash
import flask
from shelljob import proc
import math
import eventlet
eventlet.monkey_patch()
from flask import Response
import serial
import time
from datetime import datetime
import json
import random
from flask.ext.bootstrap import Bootstrap
from flask_bootstrap import WebCDN
app = flask.Flask(__name__)
app.secret_key = 'some_secret'
bootstrap = Bootstrap(app)
app.extensions['bootstrap']['cdns']['jquery'] = WebCDN('//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/')
arduino= serial.Serial( '/dev/ttyACM0' , 9600) #creating object
#app.route('/')
def home():
return render_template('status.html')
#app.route('/a',methods=['GET'])
def a():
mydata=arduino.readline().split(',')
return jsonify(m=float(mydata[0]),n=float(mydata[1]),o=float(mydata[2]),p=float(mydata[3]),q=float(mydata[4]),r=float(mydata[5]))
if __name__ == "__main__":
app.run()
It seems like you're not calling updatevalues in Javascript. You should try with something like this:
setInterval(updatevalues, 1000); //So it runs the function every 1000ms (1 second)

How to scrape text in a href by Beautiful Soup?

I have a href in format <a href="javascript:ShowImg('../UploadFile/Images/c/1/B_27902.jpg');">, and I want to get the url with '../UploadFile/Images/c/1/B_27902.jpg'. I used a stupid way to get it:( I want to know if there is a more easier way to get it.
url = '<a href="javascript:ShowImg('../UploadFile/Images/c/1/B_27902.jpg');">'
html = url.get('href')
html = html.replace('javascript:ShowImg(', '').replace(');', '')
The original tag as below:
<a href="javascript:ShowImg('../UploadFile/Images/c/1/B_27902.jpg');">
<img height="110" onerror="this.src='../UploadFile/Images/no_pic_big.jpg';"
src="../UploadFile/Images/c/1/S_27902.jpg" width="170"/>
</a>
BeautifulSoup can apply a compiled regular expression pattern to attribute values when searching for elements. You then can use the same pattern to extract the desired part of it:
import re
from bs4 import BeautifulSoup
data = """
<a href="javascript:ShowImg('../UploadFile/Images/c/1/B_27902.jpg');">
<img height="110" onerror="this.src='../UploadFile/Images/no_pic_big.jpg';"
src="../UploadFile/Images/c/1/S_27902.jpg" width="170"/>
</a>
"""
soup = BeautifulSoup(data, "html.parser")
pattern = re.compile(r"javascript:ShowImg\('(.*?)'\);")
href = soup.find('a', href=pattern)["href"]
link = pattern.search(href).group(1)
print(link) # prints ../UploadFile/Images/c/1/B_27902.jpg

evaluateJavaScript() only works once

I have the following code:
HTML + JavaScript
<style type="text/css">
.color1{
color: #3D8BD0;
}
</style>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<body>
<div id="mensagem">Mensage</div>
<script>
$("#mensagem").click(function( event ) {
printer.text('Hello');
});
</script>
</body>
And the .py file:
# -*- coding:utf-8 -*-
import sys
from PySide.QtCore import Slot, QObject, QUrl
from PySide.QtGui import QApplication
from PySide.QtWebKit import QWebView
from threading import Timer
class Dac(QObject):
def __init__(self, parent=None):
super(Dac, self).__init__(parent)
self.defultMsg = "default"
self.app = QApplication(sys.argv)
self.view = QWebView()
self.view.resize(445, 791)
self.view.load(QUrl("./page.html"))
self.frame = self.view.page().mainFrame()
self.frame.addToJavaScriptWindowObject('printer', self)
self.view.show()
self.app.exec_()
sys.exit(self.app.exec_())
def changeText(self, mensagem):
print mensagem
self.frame.evaluateJavaScript(mensagem)
#Slot(str)
def text(self, message):
print message
strm = '$("#mensagem").html("'+message+'").addClass("color1");'
self.changeText(strm) #this change the text
t = Timer(6.5, self.timeoff)
t.start()
def timeoff(self):
strm = '$("#mensagem").html("'+self.defultMsg+'").removeClass("color1");'
self.changeText(strm) #this don't change
print "debug"
dac = Dac()
When I run the Python file, the window opens and shows me the HTML page, then when I click in the div "mensagem" the text just changes one time.
So I think my problem is that the statement self.frame.evaluateJavaScript(mensagem) only works on the first time.
Is there anyone else with the same problem?
The callback you provide to threading.Timer will not be executed by the main thread. Since QWebView inherits from QWidget, you have to interact with it from the main thread:
Although QObject is reentrant, the GUI classes, notably QWidget and all its subclasses, are not reentrant. They can only be used from the main thread.
You can fix this by using PySide.QtCore.QTimer and replacing this code:
t = Timer(6.5, self.timeoff)
t.start()
With:
QTimer.singleShot(6.5 * 1000, self.timeoff)
QTimer works with Qt's event loop and therefore stays in the same thread.

Categories

Resources