Beispiel #1
0
 def test_enclosing_size(self):
     """Test enclosing size helper function"""
     sizes = [(3, 5), (1, 1), (1, 1)]
     pos = [(0, 0), (3, 0), (0, 5)]
     width, height = rpack.enclosing_size(sizes, pos)
     self.assertEqual(width, 4)
     self.assertEqual(height, 6)
Beispiel #2
0
def _bbox_rpack(component_sizes, pad_x=1.0, pad_y=1.0):
    """Compute bounding boxes for individual components
    by arranging them as densly as possible.

    Depends on `rectangle-packer`.
    """
    try:
        import rpack
    except ImportError:
        raise ImportError(
            "Using the 'components layout' requires the installation of "
            "the `rectangle-packer`. You can install it with "
            "`pip install rectangle-packer`.")

    dimensions = [_get_bbox_dimensions(n, power=0.8) for n in component_sizes]
    # rpack only works on integers; sizes should be in descending order
    dimensions = [(int(width + pad_x), int(height + pad_y))
                  for (width, height) in dimensions[::-1]]
    origins = rpack.pack(dimensions)
    outer_dimensions = rpack.enclosing_size(dimensions, origins)
    aspect_ratio = outer_dimensions[0] / outer_dimensions[1]
    if aspect_ratio > 1:
        scale_width, scale_height = 1, aspect_ratio
    else:
        scale_width, scale_height = aspect_ratio, 1
    bboxes = [(
        x,
        y,
        width * scale_width - pad_x,
        height * scale_height - pad_y,
    ) for (x, y), (width, height) in zip(origins, dimensions)]
    return bboxes[::-1]
Beispiel #3
0
def plot_circums(directory):

    data = load_simple(directory, 'circum')

    f = list()
    for (rec, pos) in data:
        w, h = rpack.enclosing_size(rec, pos)
        a = sum(x * y for x, y in rec)
        f.append(a / (w * h))

    with PdfPages(os.path.join(args.output_dir, 'circum.pdf')) as pdf:

        fig, ax = plt.subplots(tight_layout=True)
        ax.plot(list(range(1, len(f) + 1)), f)
        ax.grid(True)
        ax.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1))
        ax.xaxis.set_major_locator(mtick.MultipleLocator(10))
        ax.set_title('Packing density, fixed circumference rectangles')
        ax.set_xlabel('Rectangle width + height (n)')
        pdf.savefig(figure=fig)
        for ext in IMG_EXT:
            plt.savefig(os.path.join(args.output_dir, f'circum_summary.{ext}'))
        fig.clf()
        plt.close()

        for n, (rec, pos) in enumerate(data, start=1):
            p = PlotPacking(rec, pos, title=f', nx1 ... 1xn, n={n}.')
            while p.feed():
                pass
            pdf.savefig(figure=p.fig)
            p.fig.clf()
            plt.close()
Beispiel #4
0
def plot_enclosing(data):
    w = list()
    h = list()

    fig, ax = plt.subplots(tight_layout=True)
    ax.grid(True)
    m = 1_000
    # the scatter plot:
    for n in [10, 20, 30, 50, 100]:
        ew = list()
        eh = list()
        for rec, pos, t in data[n, m]:
            w, h = rpack.enclosing_size(rec, pos)
            ew.append(w)
            eh.append(h)
        ew = np.array(ew) / math.sqrt(n)
        eh = np.array(eh) / math.sqrt(n)
        # f = [aa/(w*h) for aa, (w, h) in zip(a, zip(ew, eh))]
        color = 'black' if n == 100 else None
        ax.scatter(ew, eh, c=color, s=0.2, label=f'$n = {n}$')

    ax.legend(markerscale=5)
    ax.set_aspect('equal')
    ax.set_xlim([0, None])
    ax.set_ylim([0, None])
    ax.set_title('Resulting enclosings,\n'
                 rf'$n$ = No. rectangles, side lengths ~ $Unif\{{1, {m}\}}$')
    ax.set_ylabel(r'Enclosing height / $\sqrt{n}$')
    ax.set_xlabel(r'Enclosing width / $\sqrt{n}$')
    for ext in IMG_EXT:
        plt.savefig(os.path.join(args.output_dir, f'enclosing.{ext}'))
    fig.clf()
    plt.close()
def get_packed(boxes):
    sizes = [(int(box[2] - box[0]), int(box[3] - box[1])) for box in boxes]
    heights = [int(box[3] - box[1]) for box in boxes]
    #arr = np.array(sizes, dtype=[('w', int), ('h', int)])
    arr = np.array(heights)

    sorted_ind = np.argsort(arr)
    sorted_ind = list(sorted_ind[::-1])
    sorted_sizes = sorted(sizes, key=lambda x: x[1], reverse=True)
    #sorted_sizes = np.sort(arr, order='h')
    #sorted_sizes = sorted_sizes[::-1]
    #sorted_sizes = list(sorted_sizes)
    #from IPython import embed
    #embed()
    positions = rpack.pack(sorted_sizes)
    shape = rpack.enclosing_size(sorted_sizes, positions)
    new_img = np.zeros((shape[1], shape[0], 3))
    for i in range(len(positions)):
        x, y = positions[i]
        w, h = sorted_sizes[i]
        box = boxes[sorted_ind[i]]
        img = cv2.imread(box[4])
        img = np.array(img)
        new_img[y:y + h, x:x + w, :] = img[int(box[1]):int(box[1]) + h,
                                           int(box[0]):int(box[0] + w)]
    return new_img
Beispiel #6
0
def plot_packing_density_by_m(data):
    n = 100
    m = 1_000
    x = list()
    total = list()
    for m in range(100, 1001, 100):
        f = list()
        for rec, pos, _ in data[100, m]:
            w, h = rpack.enclosing_size(rec, pos)
            a = sum(x * y for x, y in rec)
            f.append(a / (w * h))
        x.append(f)
        total.extend(f)
    x.append(total)

    fig, ax = plt.subplots(tight_layout=True)
    ax.axhline(np.array(total).mean(),
               color=matplotlib.rcParams['boxplot.meanprops.markerfacecolor'],
               linewidth=1,
               linestyle=':')
    bplot = ax.boxplot(
        x,
        sym='.',
        vert=True,
        patch_artist=True,
        labels=list(range(100, 1001, 100)) + ['total'],
        # positions=list(range(1, 11)) + [11.25],
        # widths=[0.5]*10 + [1],
        showmeans=True,
        medianprops=dict(color='black'))
    # fill with colors
    colors = ['lightblue'] * 10 + ['lightgreen']
    for patch, color in zip(bplot['boxes'], colors):
        patch.set_facecolor(color)
    # ax.set_xlim([None, 13])
    ax.yaxis.grid(True)
    ax.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1, decimals=0))
    ax.yaxis.set_major_locator(mtick.MultipleLocator(0.01))
    ax.yaxis.set_minor_locator(mtick.MultipleLocator(0.001))
    ax.set_title('Packing density')
    ax.set_xlabel(
        rf'rectangle side lengths ~ $Unif\{{1, m\}}$, ${n} \leq m \leq {m}$')

    for ext in IMG_EXT:
        plt.savefig(
            os.path.join(args.output_dir, f'packing_density_by_m.{ext}'))
    fig.clf()
    plt.close()
Beispiel #7
0
    def proportional(self, min_size: int = 32, album_count: int = 100) -> None:
        """

        :param min_size: the smallest size for an album in pixels
        :param album_count: the number of albums to include in the poster
        :return: None
        """
        from rpack import pack, enclosing_size
        if self.album_data is None or len(self.album_data.index) < album_count:
            album_data = get_album_data(album_count, genre_tags=self.genre_tags)
        else:
            album_data = self.album_data
        album_sizes = album_data["msPlayed"].astype(float)
        album_sizes = album_sizes / min(album_sizes) * min_size
        album_sizes = [(int(n), int(n)) for n in album_sizes]
        new_poss = pack(album_sizes)
        self.album_data = album_data
        self.positions = new_poss
        self.album_sizes = album_sizes
        self.size = enclosing_size(album_sizes, new_poss)
Beispiel #8
0
def plot_squares(directory):

    data = load_simple(directory, 'square')

    f = list()
    for (rec, pos) in data:
        w, h = rpack.enclosing_size(rec, pos)
        a = sum(x * y for x, y in rec)
        f.append(a / (w * h))

    with PdfPages(os.path.join(args.output_dir, 'squares.pdf')) as pdf:

        fig, ax = plt.subplots(tight_layout=True)
        ax.plot(list(range(1, len(f) + 1)), f)
        ax.grid(True)
        ax.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1))
        ax.xaxis.set_major_locator(mtick.MultipleLocator(10))
        ax.set_title('Packing density, squares')
        ax.set_xlabel('Rectangle max side length (n)')
        pdf.savefig(figure=fig)
        for ext in IMG_EXT:
            plt.savefig(os.path.join(args.output_dir,
                                     f'squares_summary.{ext}'))
        fig.clf()
        plt.close()

        for n, (rec, pos) in enumerate(data, start=1):
            if n == 1:
                title = ', square 1x1'
            elif n == 2:
                title = ', squares 1x1 + 2x2'
            else:
                title = f', squares 1x1 ... {n}x{n}'
            p = PlotPacking(rec, pos, title=title)
            while p.feed():
                pass
            pdf.savefig(figure=p.fig)
            p.fig.clf()
            plt.close()
Beispiel #9
0
 def __init__(self, rec, pos, gridlines=False, title='', trim=False):
     """Initialization of PlotPacking"""
     self.rec = rec
     self.pos = pos
     self.gridlines = gridlines
     self.index = None
     self.encl_w, self.encl_h = rpack.enclosing_size(rec, pos)
     self.density = sum(w * h for w, h in rec) / (self.encl_w * self.encl_h)
     if trim:
         self.fig = plt.figure(figsize=(6, 6 * self.encl_h / self.encl_w))
         self.ax = self.fig.add_axes([0.01, 0.01, 0.98, 0.98])
     else:
         self.fig, self.ax = plt.subplots(tight_layout=True)
         self.ax.set_aspect('equal')
     self.ax.invert_yaxis()
     self.ax.set_xlim([0, self.encl_w])
     self.ax.set_ylim([self.encl_h, 0])
     self.ax.xaxis.set_visible(False)
     self.ax.yaxis.set_visible(False)
     if title and not trim:
         self.ax.set_title(f'Packing density {100*self.density:.2f}% '
                           f'({self.encl_w} x {self.encl_h})' + title)
Beispiel #10
0
def plot_packing_density_by_n(data):
    m = 1_000
    x = list()
    for n in range(10, 101, 10):
        f = list()
        for rec, pos, _ in data[n, m]:
            w, h = rpack.enclosing_size(rec, pos)
            a = sum(x * y for x, y in rec)
            f.append(a / (w * h))
        x.append(f)

    fig, ax = plt.subplots(tight_layout=True)
    bplot = ax.boxplot(x,
                       sym='.',
                       vert=True,
                       patch_artist=True,
                       showfliers=True,
                       labels=list(range(10, 101, 10)),
                       showmeans=True,
                       medianprops=dict(color='black'))
    # fill with colors
    for patch in bplot['boxes']:
        patch.set_facecolor('lightblue')
    # ax.set_ylim([0.7, None])
    ax.yaxis.grid(True)
    ax.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1, decimals=0))
    ax.yaxis.set_major_locator(mtick.MultipleLocator(0.05))
    ax.yaxis.set_minor_locator(mtick.MultipleLocator(0.01))
    ax.set_title(
        rf'Packing density, rectangle side lengths ~ $Unif\{{1, {m}\}}$')
    ax.set_xlabel('Number of rectangles')

    for ext in IMG_EXT:
        plt.savefig(
            os.path.join(args.output_dir, f'packing_density_by_n.{ext}'))
    fig.clf()
    plt.close()
Beispiel #11
0
 def test_medium_pack(self):
     sizes = [(i, i) for i in range(20, 1, -1)]
     pos = rpack.pack(sizes)
     width, height = rpack.enclosing_size(sizes, pos)
     self.assertLessEqual(width*height, 3045)
Beispiel #12
0
 def test_basic_pack(self):
     """Basic pack: four 2x2 and one 3x3"""
     sizes = [(2, 2), (2, 2), (2, 2), (3, 3)]
     pos = rpack.pack(sizes)
     width, height = rpack.enclosing_size(sizes, pos)
     self.assertEqual(width*height, 25)
Beispiel #13
0
# In[10]:

b = '0' * len(sizes)
num = int(b)
Areas = {}
Positions = {}
Sizes = {}
for i in range(2**len(sizes)):
    temp = [list(i) for i in sizes]
    s = bin(num)[2:].zfill(len(sizes))
    for j in range(len(sizes)):
        if s[j] == '1':
            temp[j][1], temp[j][0] = temp[j][0], temp[j][1]
    temp = [tuple(j) for j in temp]
    positions = rpack.pack(temp)
    t = rpack.enclosing_size(temp, positions)
    Areas[s] = t[0] * t[1]
    Positions[s] = positions
    Sizes[s] = temp
    num += 1
mArea = min(Areas.values())
for k, v in Areas.items():
    if v == mArea:
        positions = Positions[k]
        sizes = Sizes[k]
        break
positions

# In[11]:

positions
Beispiel #14
0
def packing_density(rec, pos):
    w, h = rpack.enclosing_size(rec, pos)
    return sum(x * y for x, y in rec) / (w * h)
    f for f in listdir(folder)
    if isfile(join(folder, f)) and (f.endswith(".png") or f.endswith(".jpg"))
]

images = []
for i in range(len(names)):
    s = "Loading {}, {}/{}".format(names[i], i + 1, len(names))
    s += " " * (84 - len(s))
    print(s, end="\r")
    images.append(Image.open(folder + names[i]))

print("\nCalculating each image position...")
print(time.time())
rectangles = [i.size for i in images]
positions = rpack.pack(rectangles)
size = rpack.enclosing_size(rectangles, positions)
print(time.time())
print(
    "\nPositions calculated! Creating a new image with size {} by {} pixels.".
    format(size[0], size[1]))

output_file = Image.new("RGBA", size)

for i in range(len(positions)):
    s = "Putting {} in final image, {}/{}".format(
        names[i].replace(".png", "").replace(".jpg", ""), i + 1, len(names))
    s += " " * (84 - len(s))
    print(s, end="\r")
    output_file.paste(images[i], positions[i])

print("\nSaving the image...")