Example #1
0
    def create_from_config(self, svg_name='avatar'):
        """Create an avatar SVG from the configuration.

        TODO:
            * Deprecate in favor of request param based view using templates.

        """
        payload = self.config
        icon_width = self.ICON_SIZE[0]
        icon_height = self.ICON_SIZE[1]

        components = [
            icon_width, icon_height,
            Line([(0, icon_height / 2), (icon_width, icon_height / 2)],
                 width=f'{icon_height}px',
                 color=f"#{payload.get('Background')}")
        ]

        for k, v in payload.items():
            if k not in [
                    'Background', 'ClothingColor', 'HairColor', 'SkinTone'
            ]:
                components.append(
                    build_avatar_component(
                        f"{v.get('component_type')}/{v.get('svg_asset')}",
                        self.ICON_SIZE))

        with NamedTemporaryFile(mode='w+', suffix='.svg') as tmp:
            avatar = Figure(*components)
            avatar.save(tmp.name)
            with open(tmp.name) as file:
                if self.profile_set.exists():
                    svg_name = self.profile_set.last().handle
                self.svg.save(f"{svg_name}.svg", File(file), save=True)
Example #2
0
    def create_pensive_cowboy_emoji(self, input, output_dir, offset):
        """
      Takes an emoji as input and applies a cowboy hat, then puts it in a city
      and tells it some bad news.
      """
        print(f"pensiving and cowboyfy-ing {input}.... haw yee.")
        # create output path, if it doesn't exist
        Path(output_dir).mkdir(parents=True, exist_ok=True)
        # get filename without path or extension
        input_filename = Path(input).stem

        # load input svg
        input_file = sg.fromfile(input)
        # move input slightly down
        input_root = input_file.getroot()
        input_root.moveto(0, offset)

        # load the all knowing pensive face svg.
        all_knowing_face = sg.fromfile('res/pensive.svg')
        # move pensive face to same spot as input svg
        all_knowing_root = all_knowing_face.getroot()
        # the pensive face is 20x26, so account for that and move it, move it.
        all_knowing_root.moveto(5, offset + 8)

        # apply the offset to the expected height
        final_height = self.standard_size + offset
        # overlay the emojis on a workspace and save that as an output svg
        Figure(f"{self.standard_size}px", f"{final_height}px", input_root,
               self.all_powerful_root,
               all_knowing_root).save(f"{output_dir}/{input_filename}.svg")
Example #3
0
def concatenate_svgs(
        svgs,
        max_columns=None,
        scale=None,
        label=False,
        size=12,
        weight="bold",
        inset=(0.1, 0.1),
):
    """Create a grid of SVGs, with a maximum number of columns.

    Parameters
    ----------
    svgs : list
        Items may be raw SVG strings,
        or any objects with a ``tostring`` or ``to_str`` method.
    max_columns : int or None
        max number of columns, or if None, only use one row
    scale : float or None
        scale the entire composition
    label : bool
        whether to add a label for each SVG (cycle through upper case letters)
    size : int
        label font size
    weight : str
        label font weight
    inset : tuple
        inset the label by x times the SVG width and y times the SVG height

    Returns
    -------
    svgutils.compose.Figure

    """
    # TODO could replace svgutils with use of lxml primitives
    from svgutils.compose import Figure, Text

    label_iter = cycle("ABCDEFGHIJKLMNOPQRSTUVWXYZ")

    svg_composes, dimensions = zip(
        *[string_to_compose(get_svg_string(svg)) for svg in svgs])
    if scale:
        [svg.scale(scale) for svg in svg_composes]
        dimensions = [(w * scale, h * scale) for (w, h) in dimensions]
    (width, height), positions = tessellate_rectangles(dimensions, max_columns)
    elements = []
    for svg, (x, y), (w, h) in zip(svg_composes, positions, dimensions):
        elements.append(svg.move(x, y))
        if label:
            elements.append(
                Text(
                    next(label_iter),
                    x=x + inset[0] * w,
                    y=y + inset[1] * h,
                    size=size,
                    weight=weight,
                ))
    return Figure(width, height, *elements)
Example #4
0
def stack_svgs(file_list, opt_file=None, canvas_size=None):
    """
    Stack materials into a .svg image
        Support .png material only
    """

    import cairosvg
    from svgutils.compose import Figure, Image #,SVG

    if not opt_file:
        opt_file = 'stack.svg'

    if canvas_size:
        canvas_w, canvas_h = canvas_size
    else:
        canvas_w, canvas_h = 0, 0
        for file in file_list:
            width, height = get_size(file)
            if width > canvas_w: canvas_w = width
            if height > canvas_h: canvas_h = height
    print('Canvas size:', (canvas_w, canvas_h))

    # if svg, convert to png first
    file_list_png = []
    for file in file_list:
        basename, ext = os.path.splitext(file)
        if ext == '.svg':
            png_file = basename + '.png'
            cairosvg.svg2png(url=file,
                             write_to=png_file)
            file_list_png.append(png_file)
        elif ext == '.png':
            file_list_png.append(file)
        else:
            raise ValueError('File type not availale!')

    image_list = []
    #
    for file in file_list_png:
        print('File:', file)
        width, height = get_size(file)
        img = Image(width, height, file)
        img.move(int((canvas_w-width)/2),
                 int((canvas_h-height)/2))
        image_list.append(img)

    Figure(canvas_w, canvas_h, *image_list).save(opt_file)
Example #5
0
    def create_cowboy_emoji(self, input, output_dir, offset):
        """
      Takes an emoji as input and applies a cowboy hat. Yeah,
      I'm glad it exists too.
      """
        print(f"cowboyfy-ing {input}.... yee haw.")
        # create output path, if it doesn't exist
        Path(output_dir).mkdir(parents=True, exist_ok=True)
        # get filename without path or extension
        input_filename = Path(input).stem

        # load input svg
        input_file = sg.fromfile(input)
        # move input slightly down
        input_root = input_file.getroot()
        input_root.moveto(0, offset)

        # apply the offset to the expected height
        final_height = self.standard_size + offset

        # overlay the emojis on a workspace and save that as an output svg
        Figure(
            f"{self.standard_size}px", f"{final_height}px", input_root,
            self.all_powerful_root).save(f"{output_dir}/{input_filename}.svg")
Example #6
0
File: utils.py Project: svipal/web
def build_avatar_svg(svg_path='avatar.svg',
                     line_color='#781623',
                     icon_size=None,
                     payload=None,
                     temp=False):
    from .models import BaseAvatar
    icon_size = icon_size or BaseAvatar.ICON_SIZE
    icon_width = icon_size[0]
    icon_height = icon_size[1]

    if payload is None:
        # Sample payload
        payload = {
            'background_color': line_color,
            'icon_size': BaseAvatar.ICON_SIZE,
            'avatar_size': None,
            'skin_tone': '#3F2918',
            'ears': {
                'item_type': '0',
            },
            'clothing': {
                'primary_color': '#18C708',
                'item_type': 'cardigan',
            },
            'head': {
                'item_type': '0',
            },
            'hair': {
                'primary_color': '#29F998',
                'item_type': '0',
            },
            'mouth': '0',
            'nose': '0',
            'eyes': '0',
            'wallpaper': None
        }

    # Build the list of avatar components
    components = [
        icon_width,
        icon_height,
        Line([(0, icon_height / 2), (icon_width, icon_height / 2)],
             width=f'{icon_height}px',
             color=payload.get('background_color')),
    ]

    customizable_components = ['clothing', 'ears', 'head', 'hair']
    flat_components = ['eyes', 'mouth', 'nose', 'wallpaper']
    multi_components = ['accessories']

    for component in customizable_components:
        if component in payload:
            primary_color = payload.get(
                component, {}).get('primary_color') or payload.get('skin_tone')
            components.append(
                build_temporary_avatar_component(
                    component_category=component,
                    component_type=payload.get(component,
                                               {}).get('item_type',
                                                       'cardigan'),
                    primary_color=primary_color,
                ))

    for component in flat_components:
        if component in payload:
            components.append(
                build_avatar_component(
                    f"{component.title()}/{payload.get(component, '0')}.svg",
                    icon_size))

    for component in multi_components:
        if component in payload:
            components.append(
                build_avatar_component(
                    f"{component.title()}/{payload.get(component)}"))

    final_avatar = Figure(*components)

    if temp:
        return final_avatar
    result_path = f'{COMPONENT_BASE}{svg_path}'
    final_avatar.save(result_path)
    return result_path
Example #7
0
def plot_locus(grange,
               groupby,
               cellannot,
               files,
               size_factor='rdepth',
               tag='RG',
               mapq=10,
               frames_before=None,
               frames_after=None,
               normalize=True,
               palettes=sc.pl.palettes.vega_20_scanpy,
               add_total=True,
               style='fill',
               binsize=50,
               binarize=False,
               frame_width=40,
               add_labels=True,
               width_overlap=18.,
               extend_window=0,
               save=None,
               **kwargs):

    if isinstance(grange, dict):
        names = [k for k in grange]
        ranges = [grange[k] for k in grange]

    elif not isinstance(grange, list):
        ranges = [grange]
        names = ['']

    elif isinstance(grange, list):
        names = [''] * len(grange)
        ranges = granges
    if frames_before is None:
        frames_before = Frame()

    if extend_window > 0:
        ranges = [_extend(gr, extend_window) for gr in ranges]

    with tempfile.TemporaryDirectory() as tmpdir:
        for i, (name, gr) in enumerate(zip(names, ranges)):
            sct = SingleCellTracks(cellannot,
                                   files,
                                   size_factor=size_factor,
                                   tag=tag,
                                   mapq=mapq)

            frame = copy.deepcopy(frames_before)
            frame.properties['title'] = name

            fig = sct.plot(gr,
                           groupby,
                           frames_before=frame,
                           frames_after=frames_after,
                           normalize=normalize,
                           palettes=palettes,
                           add_total=add_total,
                           style=style,
                           binsize=binsize,
                           add_labels=add_labels if i == (len(names) -
                                                          1) else False,
                           binarize=binarize,
                           **kwargs)
            fig.savefig(os.path.join(tmpdir, f'{name}_{gr}.svg'))

        panel = SVG(os.path.join(tmpdir, f'{name}_{gr}.svg'))
        width, height = panel.width, panel.height

        composite_figure = Figure(
            f"{(width-width_overlap)*len(names)+width_overlap}pt",
            f"{height}pt", *[
                SVG(os.path.join(tmpdir, f'{name}_{gr}.svg')).move(
                    (width - width_overlap) * i, 0)
                for i, (name, gr) in enumerate(zip(names, ranges))
            ])
        if save is not None:
            composite_figure.save(save)
            os.makedirs(save.split('.')[0], exist_ok=True)
            for name, gr in zip(names, ranges):
                shutil.copy(os.path.join(tmpdir, f'{name}_{gr}.svg'),
                            save.split('.')[0])

    return composite_figure
Example #8
0
#!/usr/bin/env python
#coding=utf-8

from sys import argv
from svgutils.compose import Figure, SVG

Figure(
    20,
    20,
    SVG(argv[1]),
    SVG(argv[2]),
).save(argv[3])
Example #9
0
def pyx_script_pmsm(ad, best_chromosome, best_idx, Q, p, proj_name):
    if proj_name is None:
        name = 'Q%dp%didx%d' % (Q, p, best_idx)
    else:
        name = 'Q%dp%didx%d%s' % (Q, p, best_idx, proj_name)

    # output location 1
    filename_cross_sectional_view = "../_pemd2020/%s.svg" % (
        "Figure_selected_optimal_design_%s" % (name))
    # output location 2
    filename_cross_sectional_view = ad.solver.output_dir + "%s.svg" % (
        "Figure_selected_optimal_design_%s" % (name))
    # output location 3
    filename_cross_sectional_view = '../release/' + "%s.svg" % (
        "Figure_selected_optimal_design_%s" % (name))

    # Plot cross section view
    import bearingless_spmsm_design
    spmsm_best = bearingless_spmsm_design.bearingless_spmsm_design(
        spmsm_template=ad.spec.acm_template,
        x_denorm=best_chromosome[:-3],
        counter=999,
        counter_loop=1)
    spmsm_best.ID = name
    import VanGogh
    tool_tikz = VanGogh.VanGogh_TikZPlotter()
    spmsm_best.draw_spmsm(
        tool_tikz, bool_pyx=True)  # collecting track_path list for tool_tikz

    # 就算可以直接画出来,也只有最小部分而已,没有做镜像和旋转!
    # tool_tikz.c.writePDFfile("../test"+proj_name)
    # tool_tikz.c.writeEPSfile("Figure_selected_optimal_design_%s"%(name))
    tool_tikz.c.writePDFfile(filename_cross_sectional_view[:-4])
    tool_tikz.c.writeSVGfile("../a")
    # print('Write to pdf file:', "../test"+proj_name)
    # raise Exception('DEBUG HERE')
    tool_tikz.c = pyx.canvas.canvas()

    # Use tool_tikz.track_path to redraw the model
    def redraw_cross_section_outline_with_pyx(tool_tikz, no_repeat_stator,
                                              no_repeat_rotor,
                                              mm_rotor_outer_radius,
                                              mm_air_gap_length,
                                              mm_rotor_outer_steel_radius,
                                              mm_rotor_inner_radius):
        # PyX
        tool_tikz.c = pyx.canvas.canvas(
        )  # clear the canvas because we want to redraw 90 deg with the data tool_tikz.track_path

        print('Index   | Path data')
        p_stator = None  #pyx.path.path()
        p_rotor = None  #pyx.path.path()
        for index, path in enumerate(
                tool_tikz.track_path
        ):  # track_path is passed by reference and is changed by mirror
            # Failed to fill the closed path, because there is no arc-like path available.
            # p = pyx.path.line(4, 0, 5, 0) << pyx.path.line(5, 0, 5, 1) << pyx.path.line(5, 1, 4, 1)
            # p.append(path.closepath())
            # tool_tikz.c.stroke(p)
            # tool_tikz.c.stroke(path.rect(0, 0, 1, 1), [pyx.style.linewidth.Thick,
            #                      pyx.color.rgb.red,
            #                      pyx.deco.filled([pyx.color.rgb.green])])

            path_mirror = deepcopy(path)
            # for mirror copy (along x-axis)
            path_mirror[1] = path[1] * -1
            path_mirror[3] = path[3] * -1
            # for mirror copy (along y-axis)
            # path_mirror[0] = path[0]*-1
            # path_mirror[2] = path[2]*-1

            bool_exclude_path = False

            # rotate path and plot
            if is_at_stator(path, mm_rotor_outer_radius, mm_air_gap_length):
                Q = no_repeat_stator
            else:
                Q = no_repeat_rotor * 2

            EPS = 1e-6
            if is_at_stator(path, mm_rotor_outer_radius, mm_air_gap_length):
                # 按照Eric的要求,把不必要的线给删了。
                if abs(path[1] + path[3]) < EPS:  # 镜像对称线
                    bool_exclude_path = True
                if abs(path[0] - path[2]) + np.cos(
                        2 * np.pi / Q / 2) < EPS:  # 旋转对称线(特别情况,tan(90°) = ∞
                    bool_exclude_path = True
                else:
                    if abs(
                            abs((path[1] - path[3]) / (path[0] - path[2])) -
                            abs(np.tan(2 * np.pi / Q / 2))) < EPS:  # 旋转对称线
                        bool_exclude_path = True

            if not is_at_stator(path, mm_rotor_outer_radius,
                                mm_air_gap_length):
                # 按照Eric的要求,把不必要的线给删了。
                if  (abs(np.sqrt(path[0]**2+path[1]**2) - mm_rotor_inner_radius)<EPS or abs(np.sqrt(path[2]**2+path[3]**2) - mm_rotor_inner_radius)<EPS) \
                    and (len(path)==4): # 转子铁芯内径到外径的直线(len(path)==4)
                    bool_exclude_path = True

            #     # 特别的是,画永磁体的时候,边界要闭合哦。
            #     if abs(np.sqrt(path[0]**2+path[1]**2) - mm_rotor_outer_steel_radius) < EPS or abs(np.sqrt(path[2]**2+path[3]**2) - mm_rotor_outer_steel_radius) < EPS:
            #         bool_exclude_path = False

            # A trick that makes sure models with different outer diameters have the same scale.
            # tool_tikz.draw_arc([125,0], [-125,0], relangle=sign*180, untrack=True)
            tool_tikz.c.fill(
                pyx.path.circle(0, 0, 125), [pyx.color.transparency(1)]
            )  # use this if THICK is used. <- Warn: Transparency not available in PostScript, proprietary ghostscript extension code inserted. (save as eps format)
            # tool_tikz.c.fill(pyx.path.circle(0, 0, 125), [pyx.color.rgb.white]) # use this if THICK is used. <- this will over-write everthing... how to change zorder?

            _ = 2 * np.pi / Q

            if True:  # full model
                for counter in range(Q):

                    # 转子:旋转复制
                    if not is_at_stator(path, mm_rotor_outer_radius,
                                        mm_air_gap_length):
                        path[0], path[1] = rotate(_, path[0], path[1])
                        path[2], path[3] = rotate(_, path[2], path[3])
                        路径 = tool_tikz.pyx_draw_path(
                            path,
                            sign=1,
                            bool_exclude_path=bool_exclude_path,
                            bool_stroke=True)
                        if 路径 is not None:
                            if p_rotor is None:
                                p_rotor = 路径
                            else:
                                p_rotor = p_rotor << 路径

                    # 定子:镜像+旋转复制
                    if is_at_stator(path, mm_rotor_outer_radius,
                                    mm_air_gap_length):

                        path[0], path[1] = rotate(_, path[0], path[1])
                        path[2], path[3] = rotate(_, path[2], path[3])
                        路径 = tool_tikz.pyx_draw_path(
                            path,
                            sign=1,
                            bool_exclude_path=bool_exclude_path,
                            bool_stroke=True)
                        # print(index, '\t|', ',\t'.join(['%g'%(el) for el in path]))
                        if 路径 is not None:
                            if p_stator is None:
                                p_stator = 路径
                            else:
                                p_stator = p_stator << 路径

                        path_mirror[0], path_mirror[1] = rotate(
                            _, path_mirror[0], path_mirror[1])
                        path_mirror[2], path_mirror[3] = rotate(
                            _, path_mirror[2], path_mirror[3])
                        路径 = tool_tikz.pyx_draw_path(
                            path_mirror,
                            sign=-1,
                            bool_exclude_path=bool_exclude_path,
                            bool_stroke=True)
                        if 路径 is not None:
                            if p_stator is None:
                                p_stator = 路径
                            else:
                                p_stator = p_stator << 路径

                    # break
            else:  # backup

                # 转子:旋转复制
                if not is_at_stator(path, mm_rotor_outer_radius,
                                    mm_air_gap_length):
                    path[0], path[1] = rotate(0.5 * np.pi - 0.5 * 0.5 * _,
                                              path[0], path[1])
                    path[2], path[3] = rotate(0.5 * np.pi - 0.5 * 0.5 * _,
                                              path[2], path[3])
                    pyx_draw_path(tool_tikz,
                                  path,
                                  sign=1,
                                  bool_exclude_path=bool_exclude_path)
                    # print(index, '\t|', ',\t'.join(['%g'%(el) for el in path]))

                    # path[0], path[1] = rotate(0.5*np.pi - 0*0.5*_, path[0], path[1])
                    # path[2], path[3] = rotate(0.5*np.pi - 0*0.5*_, path[2], path[3])
                    # pyx_draw_path(tool_tikz, path, sign=1, bool_exclude_path=bool_exclude_path)

                # 定子:镜像+旋转复制
                if is_at_stator(path, mm_rotor_outer_radius,
                                mm_air_gap_length):

                    path[0], path[1] = rotate(0.5 * np.pi - 0.5 * _, path[0],
                                              path[1])
                    path[2], path[3] = rotate(0.5 * np.pi - 0.5 * _, path[2],
                                              path[3])
                    pyx_draw_path(tool_tikz,
                                  path,
                                  sign=1,
                                  bool_exclude_path=bool_exclude_path)
                    # print(index, '\t|', ',\t'.join(['%g'%(el) for el in path]))

                    path_mirror[0], path_mirror[1] = rotate(
                        0.5 * np.pi - 0.5 * _, path_mirror[0], path_mirror[1])
                    path_mirror[2], path_mirror[3] = rotate(
                        0.5 * np.pi - 0.5 * _, path_mirror[2], path_mirror[3])
                    pyx_draw_path(tool_tikz,
                                  path_mirror,
                                  sign=-1,
                                  bool_exclude_path=bool_exclude_path)

                    # 注意,所有 tack_path 中的 path 都已经转动了90度了!
                    # for mirror copy (along y-axis)
                    path[0] *= -1
                    path[2] *= -1
                    pyx_draw_path(tool_tikz,
                                  path,
                                  sign=-1,
                                  bool_exclude_path=bool_exclude_path)

                    path_mirror[0] *= -1
                    path_mirror[2] *= -1
                    pyx_draw_path(tool_tikz,
                                  path_mirror,
                                  sign=1,
                                  bool_exclude_path=bool_exclude_path)

        # You can have a cool logo if you un-comment this...
        # tool_tikz.c.fill(p_stator, [pyx.color.gray(0.8)])
        # tool_tikz.c.fill(p_rotor, [pyx.color.gray(0.4)])
        # tool_tikz.c.stroke(p_stator)
        # tool_tikz.c.stroke(p_rotor)

    if True:  # Draw the outline?
        redraw_cross_section_outline_with_pyx(
            tool_tikz, spmsm_best.Q, spmsm_best.p,
            spmsm_best.Radius_OuterRotor, spmsm_best.Length_AirGap,
            spmsm_best.Radius_OuterRotorSteel, spmsm_best.Radius_InnerRotor)
        # tool_tikz.c.writePDFfile("../Test_Fill_Plot" + proj_name)
        tool_tikz.c.writeSVGfile("../b")
        tool_tikz.c.writePDFfile(filename_cross_sectional_view[:-4] +
                                 'outline')
        print('Final cross sectional outline files are printed to',
              filename_cross_sectional_view[:-4] + 'outline')
        # tool_tikz.c.writePDFfile("Figure_selected_optimal_design_%s"%(name))
        # tool_tikz.c.writeEPSfile("Figure_selected_optimal_design_%s"%(name))
        # tool_tikz.c.writeSVGfile("Figure_selected_optimal_design_%s"%(name))
        # print('Write to pdf file: Figure_selected_optimal_design_%s.pdf.'%(name))
        # os.system('start %s'%("selected_optimal_design%s.pdf"%(spmsm_best.name)))
        # quit()

        # Option 1
        if True:
            from svgutils.compose import Figure, SVG  # https://svgutils.readthedocs.io/en/latest/tutorials/composing_multipanel_figures.html

            Figure(
                "5cm",
                "5cm",
                SVG("../a.svg"),
                SVG("../b.svg"),  # the order of a and b matters.
            ).save(filename_cross_sectional_view)
            os.system(
                'inkscape --file=%s --export-area-drawing --without-gui --export-pdf=%s.pdf'
                % (filename_cross_sectional_view,
                   filename_cross_sectional_view[:-4]))

        else:

            # Option 2
            import svgutils.transform as sg

            #create new SVG figure
            fig = sg.SVGFigure("16cm", "6.5cm")

            # load matpotlib-generated figures
            fig1 = sg.fromfile('../a.svg')
            fig2 = sg.fromfile('../b.svg')

            # get the plot objects
            plot1 = fig1.getroot()
            plot2 = fig2.getroot()
            # plot2.moveto(280, 0, scale=0.5)

            # append plots and labels to figure
            fig.append([plot1, plot2])
            fig.save("../d.svg")