class ScatterBuilder(XYBuilder): """This is the Scatter class and it is in charge of plotting Scatter charts in an easy and intuitive way. Essentially, we provide a way to ingest the data, make the proper calculations and push the references into a source object. We additionally make calculations for the ranges. And finally add the needed glyphs (markers) taking the references from the source. """ default_attributes = {'color': ColorAttr(), 'marker': MarkerAttr()} def yield_renderers(self): """Use the marker glyphs to display the points. Takes reference points from data loaded at the ColumnDataSource. """ for group in self._data.groupby(**self.attributes): glyph = PointGlyph(label=group.label, x=group.get_values(self.x.selection), y=group.get_values(self.y.selection), line_color=group['color'], fill_color=group['color'], marker=group['marker']) self.add_glyph(group, glyph) for renderer in glyph.renderers: yield renderer
def prepare_and_draw_matrix(dh_mat2, heading_list, disc_list, outfile): totals = {} for d in disc_list: total = 0 for h in heading_list: if( dh_mat2[h].get(d, None) is not None): total += dh_mat2[h][d] totals[d] = total section = [] d_type = [] percent = [] for d in disc_list: for h in heading_list: if( dh_mat2[h].get(d, None) is None): section.append(h) d_type.append(d) percent.append(0.0) else : section.append(h) d_type.append(d) percent.append(100.0 * dh_mat2[h][d] / totals[d]) data = {'Section': section, 'Discourse Type': d_type, 'Percentage': percent } color = ColorAttr(bin=True, palette=gray(6), sort=True, ascending=False) hm = HeatMap(data, x='Discourse Type', y='Section', values='Percentage', stat=None, plot_height=260, legend=False, color=color) output_file(outfile+'1.html', mode='cdn', root_dir=None) save(hm) hm1 = HeatMap(data, x='Discourse Type', y='Section', values='Percentage', stat=None, plot_height=260, legend=True, color=color) output_file(outfile+'2.html', mode='cdn', root_dir=None) save(hm1) '''
class TestBuilder(Builder): default_attributes = {'color': ColorAttr()} x = Dimension('x') y = Dimension('y') dimensions = ['x', 'y']
class ChordBuilder(Builder): """ This is the Chord builder and it is in charge of plotting Chord graphs in an easy and intuitive way. Essentially, we provide a way to ingest the data, make the proper calculations and push the references into a source object. We additionally make calculations for the ranges. And finally add the needed glyphs (markers) taking the references from the source. """ default_attributes = {'color': ColorAttr(), 'marker': MarkerAttr(), 'stack': CatAttr()} dimensions = ['values'] values = Dimension('values') arcs_data = Instance(ColumnDataSource) text_data = Instance(ColumnDataSource) connection_data = Instance(ColumnDataSource) origin = String() destination = String() value = Any() square_matrix = Bool() label = Seq(Any()) matrix = Array(Array(Either(Float(), Int()))) def set_ranges(self): rng = 1.1 if not self.label else 1.8 self.x_range = Range1d(-rng, rng) self.y_range = Range1d(-rng, rng) def setup(self): # Process only if not a square_matrix if not self.square_matrix: source = self.values._data[self.origin] target = self.values._data[self.destination] union = source.append(target).unique() N = union.shape[0] m = pd.DataFrame(np.zeros((N, N)), columns=union, index=union) if not self.label: self.label = list(union) if self.value is None: for _, row in self.values._data.iterrows(): m[row[self.origin]][row[self.destination]] += 1 self.matrix = m.get_values() if self.value is not None: if isinstance(self.value, int) or isinstance(self.value, float): for _, row in self.values._data.iterrows(): m[row[self.origin]][row[self.destination]] = self.value self.matrix = m.get_values() elif isinstance(self.value, str): for _, row in self.values._data.iterrows(): m[row[self.origin]][row[self.destination]] = row[self.value] self.matrix = m.get_values().T else: # It's already a square matrix self.matrix = self._data.df.get_values() if self.label: assert len(self.label) == self.matrix.shape[0] def process_data(self): weights_of_areas = (self.matrix.sum(axis=0) + self.matrix.sum(axis=1)) - self.matrix.diagonal() areas_in_radians = (weights_of_areas / weights_of_areas.sum()) * (2 * pi) # We add a zero in the begging for the cumulative sum points = np.zeros((areas_in_radians.shape[0] + 1)) points[1:] = areas_in_radians points = points.cumsum() colors = [color_in_equal_space(area / areas_in_radians.shape[0]) for area in range(areas_in_radians.shape[0])] arcs_data = pd.DataFrame({ 'start_angle': points[:-1], 'end_angle': points[1:], 'line_color': colors }) self.arcs_data = ColumnDataSource(arcs_data) # Text if self.label: text_radius = 1.1 angles = (points[:-1]+points[1:])/2.0 text_positions = pd.DataFrame({ 'angles': angles, 'text_x': np.cos(angles) * text_radius, 'text_y': np.sin(angles) * text_radius, 'text': list(self.label) }) self.text_data = ColumnDataSource(text_positions) # Lines all_areas = [] for i in range(areas_in_radians.shape[0]): all_areas.append(Area(weights_of_areas[i], points[:-1][i], points[1:][i])) all_connections = [] for j, region1 in enumerate(self.matrix): # Get the connections origin region source = all_areas[j] color = colors[j] weight = weights_of_areas[j] for k, region2 in enumerate(region1): # Get the connection destination region target = all_areas[k] for _ in range(int(region2)): p1 = source.free_points.pop() p2 = target.free_points.pop() # Get both regions free points and create a connection with the data all_connections.append(p1 + p2 + [color, weight]) connections_df = pd.DataFrame(all_connections, dtype=str) connections_df.columns = ["start_x", "start_y", "end_x", "end_y", "colors", "weight"] connections_df["cx0"] = connections_df.start_x.astype("float64")/2 connections_df["cy0"] = connections_df.start_y.astype("float64")/2 connections_df["cx1"] = connections_df.end_x.astype("float64")/2 connections_df["cy1"] = connections_df.end_y.astype("float64")/2 connections_df.weight = (connections_df.weight.astype("float64")/connections_df.weight.astype("float64").sum()) * 3000 self.connection_data = ColumnDataSource(connections_df) def yield_renderers(self): """Use the marker glyphs to display the arcs and beziers. Takes reference points from data loaded at the ColumnDataSource. """ beziers = Bezier(x0='start_x', y0='start_y', x1='end_x', y1='end_y', cx0='cx0', cy0='cy0', cx1='cx1', cy1='cy1', line_alpha='weight', line_color='colors') yield GlyphRenderer(data_source=self.connection_data, glyph=beziers) arcs = Arc(x=0, y=0, radius=1, line_width=10, start_angle='start_angle', end_angle='end_angle', line_color='line_color') yield GlyphRenderer(data_source=self.arcs_data, glyph=arcs) if self.label: text_props = { "text_color": "#000000", "text_font_size": "8pt", "text_align": "left", "text_baseline": "middle" } labels = Text(x='text_x', y='text_y', text='text', angle='angles', **text_props ) yield GlyphRenderer(data_source=self.text_data, glyph=labels)