def add_hatching(self, angle=45, distance=3, width=1, color="#000"): """ Add hatching to the walls. angle - angle of hatches in deg distance - distance between hatches width - stroke-width **Replaces all previously added hatchings or fillings.** """ if hasattr(self, "filling"): del self.filling angle = math.radians(angle) style = "stroke: {color}; stroke-width: {width}".format(color=color, width=width) pattern_width = distance / math.sin(angle) pattern_height = pattern_width * math.tan(angle) self.hatch = pattern.Pattern((0, 0), (pattern_width, pattern_height), id=self._hatching_id, patternUnits="userSpaceOnUse") self.hatch.add( shapes.Rect((0, 0), (pattern_width, pattern_height), fill="#fff")) self.hatch.add( shapes.Line((0, 0), (pattern_width, pattern_height), style=style)) self.hatch.add( shapes.Line((-1, (pattern_height - 1)), (1, (pattern_height + 1)), style=style)) self.hatch.add( shapes.Line(((pattern_width - 1), -1), ((pattern_width + 1), 1), style=style)) return self.hatch
def _draw(self): res = [] # Draw lines unit_vector = self._get_perpendicular_unit_vector( self.start_point, self.end_point, self.start_point) # inverse unit vector if needed if self._direction: unit_vector = [-part for part in unit_vector] start_extension_point = (self.start_point[0] + unit_vector[0] * self.extension_size, self.start_point[1] + unit_vector[1] * self.extension_size) end_extension_point = (self.end_point[0] + unit_vector[0] * self.extension_size, self.end_point[1] + unit_vector[1] * self.extension_size) start_extension_line = shapes.Line(self.start_point, start_extension_point, **self.attribs) end_extension_line = shapes.Line(self.end_point, end_extension_point, **self.attribs) dimension_size = self.extension_size - self.EXTENSION_TAIL start_dimension_point = (self.start_point[0] + unit_vector[0] * dimension_size, self.start_point[1] + unit_vector[1] * dimension_size) end_dimension_point = (self.end_point[0] + unit_vector[0] * dimension_size, self.end_point[1] + unit_vector[1] * dimension_size) dimension_line = shapes.Line(start_dimension_point, end_dimension_point, **self.attribs) res += [start_extension_line, end_extension_line, dimension_line] # Draw arrows start_arrow_point = self._get_middle_point(start_dimension_point, end_dimension_point, self.ARROW_LENGTH) end_arrow_point = self._get_middle_point(end_dimension_point, start_dimension_point, self.ARROW_LENGTH) res.append( self._create_arrow(start_dimension_point, end_dimension_point, start_arrow_point)) res.append( self._create_arrow(end_dimension_point, start_dimension_point, end_arrow_point)) # Draw text res.append( self._render_text(start_dimension_point, end_dimension_point)) return res
def _get_table_line(self, start, end): """ Create table line with relative coordinates """ base = (self.width - 10 - 185, self.height - 10 - 55) return shapes.Line((start[0] + base[0], start[1] + base[1]), (end[0] + base[0], end[1] + base[1]), **self.LINE_ATTRIBS)
def _get_table_line(self, start, end): """ Create table line with relative coordinates """ return shapes.Line( (start[0] + self._base_point[0], start[1] + self._base_point[1]), (end[0] + self._base_point[0], end[1] + self._base_point[1]), **self.LINE_ATTRIBS)
def draw_diagram(self) -> None: n_countries: int = self.model.rowCount() if n_countries > 0: style: SvgStyle = self.svg_style delta_angle: float = 2.0*math.pi/n_countries max_value: float = max(self.model.values) dwg = Drawing(self.temp_svg_file.fileName(), profile='tiny', viewBox='-250 -250 500 500') for idx, v in enumerate(self.model.values): x: float = style.line_length * v/max_value * math.sin(idx * delta_angle) y: float = -style.line_length * v/max_value * math.cos(idx * delta_angle) dwg.add(shapes.Line(start=(0, 0), end=(x, y), stroke=style.line_color, stroke_width=style.line_width)) radius: float = style.circle_rad if style.circle_rad_normalization: radius *= v/max_value dwg.add(shapes.Circle(center=(x, y), r=radius, stroke=style.circle_stroke_color, stroke_width=style.circle_stroke_width, fill=style.circle_fill_color)) dwg.save(pretty=True) self.load_svg(self.temp_svg_file.fileName())
def _draw(self): res = [] start_middle_point = self._get_middle_point(self.start_point, self.end_point, self.ARROW_LENGTH) end_middle_point = self._get_middle_point(self.end_point, self.start_point, self.ARROW_LENGTH) # Prepare svg elements arrow_start = self._create_arrow(self.start_point, self.end_point, start_middle_point) arrow_end = self._create_arrow(self.end_point, self.start_point, end_middle_point) line = shapes.Line(start_middle_point, end_middle_point, **self.attribs) # Create list with correct sequence of svg objects res.append(line) res.append(arrow_start) res.append(arrow_end) res.append(self._render_text(self.start_point, self.end_point)) return res
def create_axes_elements( axes, window_size, *, length=15, font_size=14, inset=(20, 20), font_offset=1.0, line_width=1, line_color="black", labels=("X", "Y", "Z"), colors=("red", "green", "blue"), ): """Create the SVG elements, related to the axes.""" svg_elements = [] for i in axes[:, 2].argsort(): a = inset[0] b = window_size[1] - inset[1] c = int(axes[i][0] * length + a) d = int(axes[i][1] * length + b) e = int(axes[i][0] * length * font_offset + a) f = int(axes[i][1] * length * font_offset + b) svg_elements.append( shapes.Line([a, b], [c, d], stroke=line_color, stroke_width=line_width)) svg_elements.append( text.Text( labels[i], x=(e, ), y=(f, ), fill=colors[i], text_anchor="middle", dominant_baseline="middle", font_size=font_size, )) return svg_elements
def draw(n): with open('netOut.json', 'r') as f: graph = json.load(f) to_remove = [i for i in range(len(graph['nodes']))] for edge in graph['edges']: if edge['source'] in to_remove: to_remove.remove(edge['source']) elif edge['target'] in to_remove: to_remove.remove(edge['target']) for i in to_remove: graph['edges'].pop(i) num_iter = 200 num_nodes = len(graph['nodes']) pos = np.random.normal(0, 1, (num_nodes, 2)) velocity = np.zeros((num_nodes, 2)) # acc = np.zeros((num_nodes, 2)) for it in range(num_iter): # Concentric force acc = -pos * 4 for i in range(num_nodes): # Repelling Force acc[i] += 20 * np.mean(1 / 5 * (pos[i] - pos), axis=0) for edge in graph['edges']: # Spring Force spring = 0.1 * (pos[edge['source']] - pos[edge['target']]) acc[edge['source']] -= spring acc[edge['target']] += spring velocity *= 0.8 velocity += acc * 0.1 pos += velocity * 0.2 print(pos[i]) # print(pos / np.argmax(np.abs(pos))) pos = pos / np.argmax(np.abs(pos)) factor = 1000000 pos = np.tanh(pos * 100) * factor sd = np.std(pos) * 0.8 chatmap = svgw.Drawing('chatmap' + str(n) + '.svg') for node in graph['nodes']: if min(abs(pos[node['id']]) < sd): chatmap.add( sh.Circle(pos[node['id']], np.sqrt(node['count']) * 0.0005 * factor, fill='orange')) for edge in graph['edges']: if min(abs(pos[edge['source']]) < sd) and min( abs(pos[edge['target']]) < sd): chatmap.add( sh.Line(pos[edge['source']], pos[edge['target']], fill='orange', style="stroke:orange;stroke-width:" + str(0.11 * edge['value']) + ';opacity:' + str(1 - 1 / edge['value']))) chatmap.save() print('CM' + str(n) + 'saved')
def generate_svg_elements(element_group, element_colors=None, background_color="white"): """Create the SVG elements, related to the 3D objects. Parameters ---------- element_group : ase_notebook.draw_elements.DrawGroup Container of all element groups to be created. background_color : str Returns ------- list[svgwrite.base.BaseElement] """ svg_elements = [] for _, element in element_group.yield_zorder(): if element.name == "atoms": if not element.get("visible", True): continue if element.occupancy is not None: from ase.data import atomic_numbers if (np.sum([o for o in element.occupancy.values()])) < 1.0: # first draw an empty circle if a site is not fully occupied svg_elements.append( shapes.Circle( element.position[:2], r=element.sradius, fill=background_color, fill_opacity=element.get("fill_opacity", 0.95), stroke=element.get("stroke", "black"), stroke_width=element.get("stroke_width", 1), )) angle_start = 0 # start with the dominant species for sym, occ in sorted(element.occupancy.items(), key=lambda x: x[1], reverse=True): if np.round(occ, decimals=4) == 1.0: svg_elements.append( shapes.Circle( element.position[:2], r=element.sradius, fill=element_colors[atomic_numbers[sym]], fill_opacity=element.get("fill_opacity", 0.95), stroke=element.get("stroke_color", "black"), stroke_width=element.get("stroke_width", 1), )) else: angle_extent = 360.0 * occ svg_elements.append( create_arc_element( element.position[:2], angle_start, angle_start + angle_extent, element.sradius, fill=element_colors[atomic_numbers[sym]], fill_opacity=element.get("fill_opacity", 0.95), stroke=element.get("stroke_color", "black"), stroke_width=element.get("stroke_width", 1), )) angle_start += angle_extent else: svg_elements.append( shapes.Circle( element.position[:2], r=element.sradius, fill=element.color, fill_opacity=element.get("fill_opacity", 0.95), stroke=element.get("stroke_color", "black"), stroke_width=element.get("stroke_width", 1), )) if "label" in element and element.label is not None: svg_elements.append( text.Text( element.label, x=(int(element.position[0]), ), y=(int(element.position[1]), ), text_anchor="middle", dominant_baseline="middle", font_size=element.get("font_size", 20), fill=element.get("font_color", "black"), )) # TODO add force/velocity vectors # TODO add ghost crosses if element.name == "cell_lines": svg_elements.append( shapes.Line( element.position[0][:2], element.position[1][:2], stroke=element.get("color", "black"), # stroke_dasharray=f"{element.get('dashed', '6,4')}", )) if element.name == "bond_lines": start, end = element.position[0][:2], element.position[1][:2] svg_elements.append( shapes.Line( start, start + 0.5 * (end - start), stroke=element.color[0], stroke_width=element.get("stroke_width", 1), stroke_linecap="round", stroke_opacity=element.get("stroke_opacity", 0.8), )) svg_elements.append( shapes.Line( start + 0.5 * (end - start), end, stroke=element.color[1], stroke_width=element.get("stroke_width", 1), stroke_linecap="round", stroke_opacity=element.get("stroke_opacity", 0.8), )) if element.name == "miller_lines": svg_elements.append( shapes.Line( element.position[0][:2], element.position[1][:2], stroke=element.get("stroke_color", "blue"), stroke_width=element.get("stroke_width", 1), stroke_opacity=element.get("stroke_opacity", 0.8), )) if element.name == "miller_planes": svg_elements.append( shapes.Polygon( points=element.position[:, :2], fill=element.get("fill_color", "blue"), fill_opacity=element.get("fill_opacity", 0.5), stroke=element.get("stroke_color", "blue"), stroke_width=element.get("stroke_width", 0), stroke_opacity=element.get("stroke_opacity", 0.5), )) return svg_elements
def _draw(self): return shapes.Line(self.start_point, self.end_point, **self.attribs)