.. raw:: latex \newpage .. _graphics: Graphics =========================== The :mod:`chama.graphics` module provides methods to help visualize results. Signal graphics --------------------------- Chama provides several functions to visualize signals described in the :ref:`simulation` section (XYZ format only). Visualization is useful to verify that the signal was loaded/generated as expected, compare scenarios, and to better understand optimal sensor placement. The convex hull of several scenarios can be generated as follows (:numref:`fig-chull`): .. doctest:: :hide: >>> import chama >>> import numpy as np >>> import pandas as pd >>> pd.set_option('display.max_columns', 20) >>> x, y, z, t = np.meshgrid([1, 2], [1, 2], [1, 2], [0, 10, 20]) >>> signal = pd.DataFrame({'X': z.flatten(),'Y': x.flatten(),'Z': y.flatten(),'T': t.flatten(), ... 'S1': [0,0,0,0.2,0.32,0.45,0.23,0.64,0.25,0.44,0.25,0.82,0.96,0.61,0.92,0.41,0.42,0,0,0,0,0,0,0], ... 'S2': [0,0,0,0.2,0.14,0.58,0.47,0.12,0.54,0.15,0.28,0.12,0.53,0.23,0.82,0.84,0.87,0.51,0,0,0,0,0,0], ... 'S3': [0,0.01,0,0.2,0.14,0.58,0.47,0.12,0.54,0.45,0.68,0.12,0.53,0.23,0.82,0.84,0.87,0.51,0.13,0,0,0,0,0]}) >>> signal = signal[['X', 'Y', 'Z', 'T', 'S1','S2', 'S3']] .. doctest:: >>> chama.graphics.signal_convexhull(signal, scenarios=['S1', 'S2', 'S3'], threshold=0.01) .. _fig-chull: .. figure:: figures/convexhull_plot.png :scale: 75 % Convex hull plot The cross section of a single scenarios can be generated as follows (:numref:`fig-xsection`): .. doctest:: >>> chama.graphics.signal_xsection(signal, 'S1', threshold=0.01) .. _fig-xsection: .. figure:: figures/xsection_plot.png :scale: 100 % Cross section plot Sensor graphics --------------------- The position of fixed and mobile sensors, described in the :ref:`sensors` section, can be plotted. After grouping sensors in a dictionary, the locations can be plotted as follows (:numref:`fig-sensorloc`): .. doctest:: :hide: >>> import chama >>> import numpy as np >>> import pandas as pd >>> sensors = {} >>> z = 20 >>> drone_path = chama.sensors.Mobile(locations=[ ... (100,100,z), (400,100,z), (420,150,z), ... (400,200,z), (100,200,z), ( 80,250,z), ... (100,300,z), (400,300,z), (420,350,z), ... (400,400,z), (100,400,z)], ... speed=0.04701, start_time=8*3600) >>> drone_camera = chama.sensors.Camera(threshold=100, ... sample_times=[0], direction=(0,0,-1)) >>> drone = chama.sensors.Sensor(position=drone_path, detector=drone_camera) >>> sensors['Drone' + str(z)] = drone >>> dist_loc = chama.sensors.Stationary(location=(100,200,5)) >>> dist_pt = chama.sensors.Point(threshold=0.1, sample_times=[0]) >>> dist = chama.sensors.Sensor(position=dist_loc, detector=dist_pt) >>> sensors['Dist1'] = dist >>> dist_loc = chama.sensors.Stationary(location=(200,300,10)) >>> dist_pt = chama.sensors.Point(threshold=0.1, sample_times=[0]) >>> dist = chama.sensors.Sensor(position=dist_loc, detector=dist_pt) >>> sensors['Dist2'] = dist >>> dist_loc = chama.sensors.Stationary(location=(200,400,8)) >>> dist_pt = chama.sensors.Point(threshold=0.1, sample_times=[0]) >>> dist = chama.sensors.Sensor(position=dist_loc, detector=dist_pt) >>> sensors['Dist3'] = dist .. doctest:: >>> chama.graphics.sensor_locations(sensors) .. doctest:: :hide: >>> #import matplotlib.pylab as plt >>> #plt.gcf() >>> #plt.savefig('sensorloc.png') .. _fig-sensorloc: .. figure:: figures/sensorloc.png :scale: 70 % Mobile and stationary sensor locations plot Tradeoff curves --------------------------- After running a series of sensor placement optimizations with increasing sensor budget, a tradeoff curve can be generated using the objective value and fraction of detected scenarios. :numref:`fig-tradeoff` compares the expected time to detection and scenario coverage as the sensor budget increases. .. _fig-tradeoff: .. figure:: figures/tradeoff.png :scale: 60 % Optimization tradeoff curve Scenario analysis --------------------------- The impact of individual scenarios can also be analyzed for a single sensor placement using the optimization assessment. :numref:`fig-scenarioimpact` compares time to detection from several scenarios, given an optimal placement. .. doctest:: :hide: >>> results = {} >>> results['Assessment'] = pd.DataFrame(data = [['S1', 'A', 4], ['S2', 'A', 5],['S3', 'B', 10],['S4', 'C', 3],['S5', 'A', 1]], ... columns=['Scenario', 'Sensor', 'Impact']) >>> results['Assessment'] = results['Assessment'][['Scenario', 'Sensor', 'Impact']] .. doctest:: >>> print(results['Assessment']) Scenario Sensor Impact 0 S1 A 4 1 S2 A 5 2 S3 B 10 3 S4 C 3 4 S5 A 1 >>> results['Assessment'].plot(kind='bar') #doctest:+SKIP .. doctest:: :hide: >>> #import matplotlib.pylab as plt >>> #plt.gcf() >>> #plt.savefig('scenarioimpact.png') .. _fig-scenarioimpact: .. figure:: figures/scenarioimpact.png :scale: 60 % Scenario impact values based on optimal placement