How to convert Holoviews graph to Bokeh 'model' in order to utilize more Bokeh features such as bokeh.models.GraphRenderer and node_renderer? - visualization

I'm trying to create a directed graph using networkx and bokeh, however, I also want to show the arrows for each out-edge. I found that the Holoviews library has the ability to add a 'directed=true' parameter to its graph constructor. However, I also want to utilize Bokeh's design features such as adjusting node color/size based on previously set node-attributes. The latter only works if I use Bokeh's from_networkx() to get a bokeh.models.renderers.GraphRender object, and then use its attributes node_renderer and edge_renderer.
The issue is when using Holoviews' renderer to specify Bokeh as the backend, it returns a bokeh.plotting.figure.Figure instead of the GraphRenderer. Ultimately, I want to be know how to be able to control the node size/color based on some attributes possible through Bokeh, and simultaneously use Holoviews to display the arrowheads on each edge.
import networkx as nx
import holoviews as hv
from holoviews import opts
hv.extension('bokeh')
from bokeh.io import show, output_file
# ... some code for I/O ...
G = nx.DiGraph(edgeList) # Directed networkx graph
# Set Node/Edge attributes to display upon hover
numConnections = {k:v for k,v in G.out_degree()}
nx.set_node_attributes(G, numConnections, name='numConnections')
# Returns Holoviews graph
hvGraph = hv.Graph.from_networkx(G, nx.spring_layout).opts(tools=['hover'], directed=True, arrowhead_length=0.01)
# Renders Holoviews graph into bokeh.plotting.figure.Figure
hvRendered = hv.render(hvGraph, 'bokeh')
output_file("out.html")
show(hvRendered)
# # The below code runs as expected using Bokeh only, and not Holoviews
# # to produce the directed graph (without arrowed edges):
# from bokeh.models import Plot, Range1d, MultiLine, Circle
# from bokeh.models import LinearColorMapper, ColorBar, BasicTicker
# import bokeh.models as bm
# from bokeh.models.graphs import from_networkx
# from bokeh.models.graphs import NodesAndLinkedEdges, EdgesAndLinkedNodes
# # Returns GraphRenderer from bokeh.models.renderers.DateRenderer
# graphRenderer = from_networkx(G, nx.spring_layout)
# mapper = LinearColorMapper(palette="Viridis256", low=76, high=0)
# # Node size/color when unselected / selected / hover
# graphRenderer.node_renderer.glyph = Circle(
# size='node_size',
# fill_color= {'field': "numConnections", "transform": mapper},
# fill_alpha=.8
# )
# graphRenderer.node_renderer.selection_glyph = Circle(
# size=25,
# fill_color=Inferno6[4]
# )
# graphRenderer.node_renderer.hover_glyph = Circle(
# size=20,
# fill_color=Inferno6[3]
# )
# # Edge size/color when unselected / selected / hover
# graphRenderer.edge_renderer.glyph = MultiLine(
# line_color="#CCCCCC",
# line_alpha=0.8,
# line_width=3
# )
# graphRenderer.edge_renderer.selection_glyph = MultiLine(
# line_color=Inferno6[4],
# line_width=4
# )
# graphRenderer.edge_renderer.hover_glyph = MultiLine(
# line_color=Inferno6[3],
# line_width=4
# )
# graphRenderer.node_renderer.data_source.data['numConnections'] = [v for k,v in
nx.get_node_attributes(G,'numConnections').items()]
# graphRenderer.selection_policy = NodesAndLinkedEdges()
# graphRenderer.inspection_policy = NodesAndLinkedEdges()
# bar = ColorBar(color_mapper=mapper, location=(0,0), title='#connections')
# # Create Bokeh Plot
# plot = Plot(
# plot_width=20,
# plot_height=20,
# x_range=Range1d(-1.1,1.1),
# y_range=Range1d(-1.1,1.1)
# )
# plot.add_tools(
# bm.HoverTool(tooltips=[("#connections", "#numConnections")]),
# bm.TapTool(),
# bm.BoxSelectTool()
# )
# plot.renderers.append(graphRenderer)
# output_file("bokeh.html")
# show(plot)
After rendering the Holoview graph into a Bokeh Figure (not a models.GraphRenderer), if I try to call the attribute node_renderer using the rendered Bokeh Figure object, it obviously throws an exception.
Traceback (most recent call last): File "holoview.py", line 106, in hvRenderedGraph.node_renderer.selection_glyph = Circle() AttributeError: 'BokehRenderer' object has no attribute 'node_renderer'

You can get the GraphRender object by following code:
from bokeh.models import GraphRenderer
gr = hvRendered.select_one(GraphRenderer)
then use gr.node_renderer and gr.edge_renderer to adjust the style.

Related

Raspberry Pi 4 Aborts SSH Connection When TensorFlow Lite Has Initialized After Running Python 3 Script

I want to use object detection using tensorflow lite in order to detect a clear face or a covered face where the statement "door opens" is printed when a clear face is detected. I could run this code smoothly previously but later after rebooting raspberry pi 4, although the tensorflow lite runtime is initialized, the raspberry pi 4 disconnects with the ssh completely. The following is the code:
######## Webcam Object Detection Using Tensorflow-trained Classifier #########
#
# Author: Evan Juras
# Date: 10/27/19
# Description:
# This program uses a TensorFlow Lite model to perform object detection on a live webcam
# feed. It draws boxes and scores around the objects of interest in each frame from the
# webcam. To improve FPS, the webcam object runs in a separate thread from the main program.
# This script will work with either a Picamera or regular USB webcam.
#
# This code is based off the TensorFlow Lite image classification example at:
# https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/examples/python/label_image.py
#
# I added my own method of drawing boxes and labels using OpenCV.
# Import packages
import os
import argparse
import cv2
import numpy as np
import sys
import time
from threading import Thread
import importlib.util
import simpleaudio as sa
# Define VideoStream class to handle streaming of video from webcam in separate processing thread
# Source - Adrian Rosebrock, PyImageSearch: https://www.pyimagesearch.com/2015/12/28/increasing-raspberry-pi-fps-with-python-and-opencv/
class VideoStream:
"""Camera object that controls video streaming from the Picamera"""
def __init__(self,resolution=(640,480),framerate=30):
# Initialize the PiCamera and the camera image stream
self.stream = cv2.VideoCapture(0)
ret = self.stream.set(cv2.CAP_PROP_FOURCC, cv2.VideoWriter_fourcc(*'MJPG'))
ret = self.stream.set(3,resolution[0])
ret = self.stream.set(4,resolution[1])
# Read first frame from the stream
(self.grabbed, self.frame) = self.stream.read()
# Variable to control when the camera is stopped
self.stopped = False
def start(self):
# Start the thread that reads frames from the video stream
Thread(target=self.update,args=()).start()
return self
def update(self):
# Keep looping indefinitely until the thread is stopped
while True:
# If the camera is stopped, stop the thread
if self.stopped:
# Close camera resources
self.stream.release()
return
# Otherwise, grab the next frame from the stream
(self.grabbed, self.frame) = self.stream.read()
def read(self):
# Return the most recent frame
return self.frame
def stop(self):
# Indicate that the camera and thread should be stopped
self.stopped = True
# Define and parse input arguments
parser = argparse.ArgumentParser()
parser.add_argument('--modeldir', help='Folder the .tflite file is located in',
required=True)
parser.add_argument('--graph', help='Name of the .tflite file, if different than detect.tflite',
default='masktracker.tflite')
parser.add_argument('--labels', help='Name of the labelmap file, if different than labelmap.txt',
default='facelabelmap.txt')
parser.add_argument('--threshold', help='Minimum confidence threshold for displaying detected objects',
default=0.5)
parser.add_argument('--resolution', help='Desired webcam resolution in WxH. If the webcam does not support the resolution entered, errors may occur.',
default='640x480')
parser.add_argument('--edgetpu', help='Use Coral Edge TPU Accelerator to speed up detection',
action='store_true')
args = parser.parse_args()
MODEL_NAME = args.modeldir
GRAPH_NAME = args.graph
LABELMAP_NAME = args.labels
min_conf_threshold = float(args.threshold)
resW, resH = args.resolution.split('x')
imW, imH = int(resW), int(resH)
use_TPU = args.edgetpu
# Import TensorFlow libraries
# If tflite_runtime is installed, import interpreter from tflite_runtime, else import from regular tensorflow
# If using Coral Edge TPU, import the load_delegate library
pkg = importlib.util.find_spec('tflite_runtime')
if pkg:
from tflite_runtime.interpreter import Interpreter
if use_TPU:
from tflite_runtime.interpreter import load_delegate
else:
from tensorflow.lite.python.interpreter import Interpreter
if use_TPU:
from tensorflow.lite.python.interpreter import load_delegate
# If using Edge TPU, assign filename for Edge TPU model
if use_TPU:
# If user has specified the name of the .tflite file, use that name, otherwise use default 'edgetpu.tflite'
if (GRAPH_NAME == 'masktracker.tflite'):
GRAPH_NAME = 'edgetpu.tflite'
# Get path to current working directory
CWD_PATH = os.getcwd()
# Path to .tflite file, which contains the model that is used for object detection
PATH_TO_CKPT = os.path.join(CWD_PATH,MODEL_NAME,GRAPH_NAME)
# Path to label map file
PATH_TO_LABELS = os.path.join(CWD_PATH,MODEL_NAME,LABELMAP_NAME)
# Load the label map
with open(PATH_TO_LABELS, 'r') as f:
labels = [line.strip() for line in f.readlines()]
# Have to do a weird fix for label map if using the COCO "starter model" from
# https://www.tensorflow.org/lite/models/object_detection/overview
# First label is '???', which has to be removed.
if labels[0] == '???':
del(labels[0])
# Load the Tensorflow Lite model.
# If using Edge TPU, use special load_delegate argument
if use_TPU:
interpreter = Interpreter(model_path=PATH_TO_CKPT,
experimental_delegates=[load_delegate('libedgetpu.so.1.0')])
print(PATH_TO_CKPT)
else:
interpreter = Interpreter(model_path=PATH_TO_CKPT)
interpreter.allocate_tensors()
# Get model details
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
height = input_details[0]['shape'][1]
width = input_details[0]['shape'][2]
floating_model = (input_details[0]['dtype'] == np.float32)
input_mean = 127.5
input_std = 127.5
# Initialize frame rate calculation
frame_rate_calc = 1
freq = cv2.getTickFrequency()
global image_capture
image_capture = 0
# Initialize video stream
videostream = VideoStream(resolution=(imW,imH),framerate=30).start()
time.sleep(1)
#for frame1 in camera.capture_continuous(rawCapture, format="bgr",use_video_port=True):
while True:
# Start timer (for calculating frame rate)
t1 = cv2.getTickCount()
# Grab frame from video stream
frame1 = videostream.read()
# Acquire frame and resize to expected shape [1xHxWx3]
frame = frame1.copy()
frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
frame_resized = cv2.resize(frame_rgb, (width, height))
input_data = np.expand_dims(frame_resized, axis=0)
# Normalize pixel values if using a floating model (i.e. if model is non-quantized)
if floating_model:
input_data = (np.float32(input_data) - input_mean) / input_std
# Perform the actual detection by running the model with the image as input
interpreter.set_tensor(input_details[0]['index'],input_data)
interpreter.invoke()
# Retrieve detection results
boxes = interpreter.get_tensor(output_details[0]['index'])[0] # Bounding box coordinates of detected objects
classes = interpreter.get_tensor(output_details[1]['index'])[0] # Class index of detected objects
scores = interpreter.get_tensor(output_details[2]['index'])[0] # Confidence of detected objects
#num = interpreter.get_tensor(output_details[3]['index'])[0] # Total number of detected objects (inaccurate and not needed)
# Loop over all detections and draw detection box if confidence is above minimum threshold
for i in range(len(scores)):
if ((scores[i] > min_conf_threshold) and (scores[i] <= 1.0)):
# Get bounding box coordinates and draw box
# Interpreter can return coordinates that are outside of image dimensions, need to force them to be within image using max() and min()
ymin = int(max(1,(boxes[i][0] * imH)))
xmin = int(max(1,(boxes[i][1] * imW)))
ymax = int(min(imH,(boxes[i][2] * imH)))
xmax = int(min(imW,(boxes[i][3] * imW)))
# Draw label
object_name = labels[int(classes[i])] # Look up object name from "labels" array using class index
if (object_name=="face unclear" ):
color = (0, 255, 0)
cv2.rectangle(frame, (xmin,ymin), (xmax,ymax),color, 2)
print("Face Covered: Door Not Opened")
if(image_capture == 0):
path = r'/home/pi/Desktop/tflite_1/photographs'
date_string = time.strftime("%Y-%m-%d_%H%M%S")
#print(date_string)
cv2.imwrite(os.path.join(path, (date_string + ".jpg")),frame)
#cv2.imshow("Photograph",frame)
#mp3File = input(alert_audio.mp3)
print("Photo Taken")
#w_object = sa.WaveObject.from_wave_file('alert_audio.wav')
#p_object = w_object.play()
#p_object.wait_done()
image_capture = 1
else:
color = (0, 0, 255)
cv2.rectangle(frame, (xmin,ymin), (xmax,ymax),color, 2)
print("Face Clear: Door Opened")
image_capture = 0
#cv2.rectangle(frame, (xmin,ymin), (xmax,ymax),color, 2)
#image = np.asarray(ImageGrab.grab())
label = '%s: %d%%' % (object_name, int(scores[i]*100)) # Example: 'person: 72%'
labelSize, baseLine = cv2.getTextSize(label, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 2) # Get font size
label_ymin = max(ymin, labelSize[1] + 10) # Make sure not to draw label too close to top of window
cv2.rectangle(frame, (xmin, label_ymin-labelSize[1]-10), (xmin+labelSize[0], label_ymin+baseLine-10), (255, 255, 255), cv2.FILLED) # Draw white box to put label text in
cv2.putText(frame, label, (xmin, label_ymin-7), cv2.FONT_HERSHEY_SIMPLEX, 0.7, (0, 0, 0), 2) # Draw label text
if ((scores[0] < min_conf_threshold)):
cv2.putText(frame,"No Face Detected",(260,260),
cv2.FONT_HERSHEY_SIMPLEX, 0.8, color=(255,0,0))
print("No Face Detected")
image_capture = 0
# Draw framerate in corner of frame
cv2.putText(frame,'FPS: {0:.2f}'.format(frame_rate_calc),(30,50),cv2.FONT_HERSHEY_SIMPLEX,1,(255,255,0),2,cv2.LINE_AA)
# All the results have been drawn on the frame, so it's time to display it.
cv2.imshow('Object detector', frame)
# Calculate framerate
t2 = cv2.getTickCount()
time1 = (t2-t1)/freq
frame_rate_calc= 1/time1
# Press 'q' to quit
if cv2.waitKey(1) == ord('q'):
break
# Clean up
cv2.destroyAllWindows()
videostream.stop()
Any help is appreciated.
Regards,
MD

How can I create an animated plot from incoming serial port data

I want to live plot incoming data from a serial port without writing and reading data from a file. I understand that it's necessary to run a thread where the serial data is coming in on the fly. While the thread is running the animation.FuncAnimation should grab the serial data and render the plot each time.
That's where I can't figure out how to code the handover to get the animation to work.
import serial
import threading
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import itertools
def thread_data_gen():
i = 0
counter = itertools.count()
ser = serial.Serial('/dev/tty.SLAB_USBtoUART', 1000000, timeout=1) # Open port and read data.
ser.reset_input_buffer() # Flush input buffer, discarding all its contents.
while True:
ser_bytes = ser.readline() # Read serial data line by line
# Incoming lines in Format -> b'$ 32079 32079 32079 32079 32079 32079 32079 32079;\r\n'
# Each value represents a data channel which can measure torque, temperatur,...
# Right now all values are set to torque which is why they have the same values.
# 8 data channels available
decoded_bytes = ser_bytes.decode('utf-8')
decoded_bytes = decoded_bytes.lstrip('$').rstrip().split()
# Re-format to ['32274', '32274', '32274', '32274', '32274', '32274', '32274', '32274;']
if i == 0:
i += 1
continue
# Skip first read-out because the first transmitted line is empty. Don't know the reason.
t = next(counter) # Create values for x-axis
y = decoded_bytes[0] # Read channel 1 values for y-axis
yield t, y # Was thinking about a generator type of return but that's not working
def run(data): # Handing over yield data from thread_data_gen()
t, y = data # TypeError:"cannot unpack non-iterable int object" I don't know how to fix this.
# I have to convert the while loop in the running thread to something where I get iterable int data.
# That's where I don't see the solution
xdata.append(t) # Adding data to list for x-values
ydata.append(y) # Adding data to list for y-values
line.set_data(xdata, ydata) # Creating data for hand-over to plt
return line,
if __name__ == '__main__':
dgen = threading.Thread(target=thread_data_gen)
dgen.start()
fig, ax = plt.subplots()
line, = ax.plot([], [], lw=2)
ax.grid()
xdata, ydata = [], []
ani = animation.FuncAnimation(fig, run, interval=100)
plt.show()
Update
I just solved my own problem with:
# A sensor upgraded coupling in a power transmission system provides data per bluetooth.
# Data: Torque, force, temperature and acceleration (x-y-z-axis).
# A hardware gateway receives the data with an antenna.
# The purpose of this code is to read and plot out serial data from that hardware gateway
# which is linked via USB-C to the laptop. A USB-C to UART software bride,
# makes the data as serial port on MacOS or Windows available.
import time
import serial
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import itertools
def data_gen():
i = 0
counter = itertools.count() # Create counter
ser = serial.Serial('/dev/tty.SLAB_USBtoUART', 1000000, timeout=1) # Open port and read data.
ser.reset_input_buffer() # Flush input buffer, discarding all its contents.
while True:
# Read serial data line by line.
# Incoming lines in Format -> b'$ 32079 32079 32079 32079 32079 32079 32079 32079;\r\n'
# Each value represents a data channel which can measure torque, temperatur, ...
# Right now all values are set to torque which is why they have the same values.
# 8 data channels are available
ser_bytes = ser.readline()
decoded_bytes = ser_bytes.decode('utf-8')
# Re-format to list ['32274', '32274', '32274', '32274', '32274', '32274', '32274', '32274;']
decoded_bytes = decoded_bytes.lstrip('$').rstrip().split()
# Skip first read-out because the first transmitted line is empty. Don't know the reason.
if i == 0:
i += 1
continue
t = next(counter) # Create values for x-axis
y = decoded_bytes[0] # Read channel 1 values for y-axis
yield t, float(y) # Yield back x and y values for plot
def run(data):
x, y = data
y_cal = round(y * 0.00166, 1) #
xdata.append(x) # Adding data to list for x-values
ydata.append(y_cal) # Adding data to list for y-values
line.set_data(xdata, ydata) # Creating a data set for hand-over to plot
return line,
if __name__ == '__main__':
fig, ax = plt.subplots() # Setup figure and axis
line, = ax.plot([], [], lw=2) # Setup line
ax.set_ylim(40, 80) # Set limitation in y
ax.set_xlim(0, 1000) # Set limitation in x
ax.grid() # Create grid
xdata, ydata = [], [] # Create empty lists
# Frames: Receives the generated data from the serial connection
# Run: Provides the line data
ani = animation.FuncAnimation(fig, run, frames=data_gen, blit=True, interval=10)
plt.show()

How I can overcome the _geoslib problem in this code?

This code is specified to visualize the CALIPSO satellite atmospheric profiles
The input files are .HDF
The code is copyrighted to the HDF group.
In the begining, I struggled with installing the basemap,
finally I installed it using .whl file on my windows10.
Now, this error is reached when I run the script:
SystemError:
execution of module _geoslib raised unreported exception.
I have looked a lot in google, but nothing done.
Can you please help me?
Cheers
"Copyright (C) 2014-2019 The HDF Group
Copyright (C) 2014 John Evans
This example code illustrates how to access and visualize a LaRC CALIPSO file
in file in Python.
If you have any questions, suggestions, or comments on this example, please use
the HDF-EOS Forum (http://hdfeos.org/forums). If you would like to see an
example of any other NASA HDF/HDF-EOS data product that is not listed in the
HDF-EOS Comprehensive Examples page (http://hdfeos.org/zoo), feel free to
contact us at eoshelp#hdfgroup.org or post it at the HDF-EOS Forum
(http://hdfeos.org/forums).
Usage: save this script and run
$python CAL_LID_L2_VFM-ValStage1-V3-02.2011-12-31T23-18-11ZD.hdf.py
The HDF file must either be in your current working directory
or in a directory specified by the environment variable HDFEOS_ZOO_DIR.
Tested under: Python 2.7.15::Anaconda custom (64-bit)
Last updated: 2019-01-25
"""
import os
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
from mpl_toolkits.basemap import Basemap
from matplotlib import colors
USE_NETCDF4 = False
def run(FILE_NAME):
# Identify the data field.
DATAFIELD_NAME = 'Feature_Classification_Flags'
if USE_NETCDF4:
from netCDF4 import Dataset
nc = Dataset(FILE_NAME)
# Subset the data to match the size of the swath geolocation fields.
# Turn off autoscaling, we'll handle that ourselves due to presence of
# a valid range.
var = nc.variables[DATAFIELD_NAME]
data = var[:,1256]
# Read geolocation datasets.
lat = nc.variables['Latitude'][:]
lon = nc.variables['Longitude'][:]
else:
from pyhdf.SD import SD, SDC
hdf = SD(FILE_NAME, SDC.READ)
# Read dataset.
data2D = hdf.select(DATAFIELD_NAME)
data = data2D[:,1256]
# Read geolocation datasets.
latitude = hdf.select('Latitude')
lat = latitude[:]
longitude = hdf.select('Longitude')
lon = longitude[:]
# Subset data. Otherwise, all points look black.
lat = lat[::10]
lon = lon[::10]
data = data[::10]
# Extract Feature Type only through bitmask.
data = data & 7
# Make a color map of fixed colors.
cmap = colors.ListedColormap(['black', 'blue', 'yellow', 'green', 'red', 'purple', 'gray', 'white'])
# The data is global, so render in a global projection.
m = Basemap(projection='cyl', resolution='l',
llcrnrlat=-90, urcrnrlat=90,
llcrnrlon=-180, urcrnrlon=180)
m.drawcoastlines(linewidth=0.5)
m.drawparallels(np.arange(-90.,90,45))
m.drawmeridians(np.arange(-180.,180,45), labels=[True,False,False,True])
x,y = m(lon, lat)
i = 0
for feature in data:
m.plot(x[i], y[i], 'o', color=cmap(feature), markersize=3)
i = i+1
long_name = 'Feature Type at Altitude = 2500m'
basename = os.path.basename(FILE_NAME)
plt.title('{0}\n{1}'.format(basename, long_name))
fig = plt.gcf()
# define the bins and normalize
bounds = np.linspace(0,8,9)
norm = mpl.colors.BoundaryNorm(bounds, cmap.N)
# create a second axes for the colorbar
ax2 = fig.add_axes([0.93, 0.2, 0.01, 0.6])
cb = mpl.colorbar.ColorbarBase(ax2, cmap=cmap, norm=norm, spacing='proportional', ticks=bounds, boundaries=bounds, format='%1i')
cb.ax.set_yticklabels(['invalid', 'clear', 'cloud', 'aerosol', 'strato', 'surface', 'subsurf', 'no signal'], fontsize=5)
# plt.show()
pngfile = "{0}.py.png".format(basename)
fig.savefig(pngfile)
if __name__ == "__main__":
# If a certain environment variable is set, look there for the input
# file, otherwise look in the current directory.
hdffile = 'CAL_LID_L2_VFM-ValStage1-V3-02.2011-12-31T23-18-11ZD.hdf'
try:
fname = os.path.join(os.environ['HDFEOS_ZOO_DIR'], ncfile)
except KeyError:
fname = hdffile
run(fname)
Please try miniconda and use basemap from conda-forge:
conda install -c conda-forge basemap

XGBoost: xgb.importance feature map

I am getting the below error when I am trying to use the following code.
******Code******
importance = bst.get_fscore(fmap='xgb.fmap')
importance = sorted(importance.items(), key=operator.itemgetter(1))
******Error******
File "scripts/xgboost_bnp.py", line 225, in <module>
importance = bst.get_fscore(fmap='xgb.fmap')
File "/usr/lib/python2.7/site-packages/xgboost/core.py", line 754, in get_fscore
trees = self.get_dump(fmap)
File "/usr/lib/python2.7/site-packages/xgboost/core.py", line 740, in get_dump
ctypes.byref(sarr)))
File "/usr/lib/python2.7/site-packages/xgboost/core.py", line 92, in _check_call
raise XGBoostError(_LIB.XGBGetLastError())
xgboost.core.XGBoostError: can not open file "xgb.fmap"
The error is raised because you are calling get_fscore with an optional parameter fmap stating that feature importance of each feature should be fetched from a feature map file called xgb.fmap, which does not exist in your file system.
Here is a function returning sorted feature names and their importances:
import xgboost as xgb
import pandas as pd
def get_xgb_feat_importances(clf):
if isinstance(clf, xgb.XGBModel):
# clf has been created by calling
# xgb.XGBClassifier.fit() or xgb.XGBRegressor().fit()
fscore = clf.booster().get_fscore()
else:
# clf has been created by calling xgb.train.
# Thus, clf is an instance of xgb.Booster.
fscore = clf.get_fscore()
feat_importances = []
for ft, score in fscore.iteritems():
feat_importances.append({'Feature': ft, 'Importance': score})
feat_importances = pd.DataFrame(feat_importances)
feat_importances = feat_importances.sort_values(
by='Importance', ascending=False).reset_index(drop=True)
# Divide the importances by the sum of all importances
# to get relative importances. By using relative importances
# the sum of all importances will equal to 1, i.e.,
# np.sum(feat_importances['importance']) == 1
feat_importances['Importance'] /= feat_importances['Importance'].sum()
# Print the most important features and their importances
print feat_importances.head()
return feat_importances

How to use ScatterInspector and ScatterInspectorOverlay?

I would like to use the chaco tools ScatterInspector and/or ScatterInspectorOverlay with enaml. I've set up a very simple controller and view (source below) but cannot determine how to proceed. I have tried unsuccessfully to follow the minimal and old examples I've found.
If I uncomment the overlay part for ScatterInspectorOverlay, the code fails to run with
File ".../chaco/scatter_inspector_overlay.py", line 51, in overlay if not plot or not plot.index or not getattr(plot, "value", True):
If I comment out the overlay part, I of course don't get the overlay behavior I want and also, on moving the mouse, get
File ".../chaco/tools/scatter_inspector.py", line 48, in normal_mouse_move index = plot.map_index((event.x, event.y), threshold=self.threshold)
view.enaml source:
from enaml.widgets.api import (
Window, Container, EnableCanvas,
)
enamldef ScatterView(Window):
attr controller
title = "Scatter Inspector Test"
initial_size = (640,480)
Container:
EnableCanvas:
component = controller.scatter_plot
controller.py source:
import enaml
from enaml.stdlib.sessions import show_simple_view
from traits.api import HasTraits, Instance
from chaco.api import Plot, ArrayPlotData, ScatterInspectorOverlay
from chaco.tools.api import ScatterInspector
from numpy import linspace, sin
class ScatterController(HasTraits):
scatter_plot = Instance(Plot)
def _scatter_plot_default(self):
# data
x = linspace(-14, 14, 100)
y = sin(x) * x**3
plotdata = ArrayPlotData(x = x, y = y)
# plot
scatter_plot = Plot(plotdata)
renderer = scatter_plot.plot(("x", "y"), type="scatter", color="red")
# inspector
scatter_plot.tools.append(ScatterInspector(scatter_plot))
# overlay
# scatter_plot.overlays.append( ScatterInspectorOverlay(
# scatter_plot,
# hover_color = 'red',
# hover_marker_size = 6,
# selection_marker_size = 6,
# selection_color = 'yellow',
# selection_outline_color='purple',
# selection_line_width = 3
# ))
#return
return scatter_plot
if __name__ == "__main__":
with enaml.imports():
from view import ScatterView
main_controller = ScatterController()
window = ScatterView(controller=ScatterController())
show_simple_view(window)
The problem with my above code was that I was adding ScatterInspector to scatter_plot rather than to renderer and that I was missing the [0] index to get renderer.
The key thing I was really wanting to do, though, was to be notified when the mouse was hovering over a data point and/or a data point was selected. I added when_hover_or_selection_changes which shows how to do that.
Working controller.py:
...
# plot
scatter_plot = Plot(plotdata)
renderer = scatter_plot.plot(("x", "y"), type="scatter", color="lightblue")[0]
# inspector
renderer.tools.append(ScatterInspector(renderer))
# overlay
renderer.overlays.append(ScatterInspectorOverlay(renderer,
hover_color="red",
hover_marker_size=6,
selection_marker_size=6,
selection_color="yellow",
selection_outline_color="purple",
selection_line_width=3))
...
# get notified when hover or selection changes
#on_trait_change('renderer.index.metadata')
def when_hover_or_selection_changes(self):
print 'renderer.index.metadata = ', self.renderer.index.metadata