{"id":19093675,"url":"https://github.com/juliaarrays/mosaicviews.jl","last_synced_at":"2025-08-15T22:19:35.410Z","repository":{"id":52912302,"uuid":"114407775","full_name":"JuliaArrays/MosaicViews.jl","owner":"JuliaArrays","description":"Julia package for lazily viewing a 3D or 4D array as an expanded 2D array in the form of a mosaic of matrix slices","archived":false,"fork":false,"pushed_at":"2024-11-06T21:52:29.000Z","size":109,"stargazers_count":25,"open_issues_count":3,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-07-24T11:48:04.833Z","etag":null,"topics":["julia"],"latest_commit_sha":null,"homepage":"","language":"Julia","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/JuliaArrays.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-12-15T20:14:24.000Z","updated_at":"2024-11-06T21:52:23.000Z","dependencies_parsed_at":"2024-10-25T01:26:57.470Z","dependency_job_id":"021231b7-80ca-4694-a8c7-d15298498691","html_url":"https://github.com/JuliaArrays/MosaicViews.jl","commit_stats":{"total_commits":57,"total_committers":6,"mean_commits":9.5,"dds":"0.49122807017543857","last_synced_commit":"7bb84dfb82532d0322220dff84825a3626700ac5"},"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/JuliaArrays/MosaicViews.jl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaArrays%2FMosaicViews.jl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaArrays%2FMosaicViews.jl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaArrays%2FMosaicViews.jl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaArrays%2FMosaicViews.jl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JuliaArrays","download_url":"https://codeload.github.com/JuliaArrays/MosaicViews.jl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JuliaArrays%2FMosaicViews.jl/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":270637772,"owners_count":24620428,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-15T02:00:12.559Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["julia"],"created_at":"2024-11-09T03:25:38.584Z","updated_at":"2025-08-15T22:19:35.383Z","avatar_url":"https://github.com/JuliaArrays.png","language":"Julia","funding_links":[],"categories":[],"sub_categories":[],"readme":"# MosaicViews\n\n[![codecov](https://codecov.io/github/JuliaArrays/MosaicViews.jl/graph/badge.svg?token=uHKmfvAz3B)](https://codecov.io/github/JuliaArrays/MosaicViews.jl)\n[![PkgEval][pkgeval-img]][pkgeval-url]\n\n## Motivations\n\nWhen visualizing images, it is not uncommon to provide a 2D view of different image sources.\nFor example, comparing multiple images of different sizes, getting a preview of machine\nlearning dataset. This package aims to provide easy-to-use tools for such tasks.\n\n## Usage\n\n### Compare two or more images\n\nWhen comparing and showing multiple images, `cat`/`hcat`/`vcat/hvcat` can be helpful if the image\nsizes and element types are the same. But if not, you'll need `mosaic` for this purpose.\n\n```julia\n# ImageCore reexports MosaicViews with some glue code for images\njulia\u003e using ImageCore, ImageShow, TestImages, ColorVectorSpace\n\njulia\u003e toucan = testimage(\"toucan\") # 150×162 RGBA image\n\njulia\u003e moon = testimage(\"moon\") # 256×256 Gray image\n\njulia\u003e mosaic(toucan, moon; nrow=1)\n```\n\n![compare-images](https://user-images.githubusercontent.com/1525481/97542758-4b5ade80-1995-11eb-87cc-5fd2b0ba23fc.png)\n\nLike `cat`, `mosaic` makes a copy of the inputs.\n\n### Get a preview of dataset\n\nMany datasets in machine learning field are stored as 3D/4D array, where different images are different slices\nalong the 3rd and 4th dimensions.\n`mosaicview` provides a convenient way to visualize a single higher-dimensional array as a 2D grid-of-images.\n\n```julia\njulia\u003e using MosaicViews, ImageShow, MLDatasets\n\njulia\u003e A = MNIST.convert2image(MNIST.traintensor(1:9))\n28×28×9 Array{Gray{Float64},3}:\n[...]\n\njulia\u003e mosaicview(A, fillvalue=.5, nrow=2, npad=1, rowmajor=true)\n57×144 MosaicViews.MosaicView{Gray{Float64},4,...}:\n[...]\n```\n\n![dataset-preview](https://user-images.githubusercontent.com/10854026/34172451-5f80173e-e4f2-11e7-9e86-8b3882d53aa7.png)\n\nUnlike `mosaic`, `mosaicview` does not copy the input--it provides an alternative interpretation of the input data.\nConsequently, if you modify pixels of the output of `mosaicview`, those modifications also apply to the parent array `A`.\n\n`mosaicview` is essentially a flexible way of constructing a `MosaicView`; it provides\nadditional customization options via keyword arguments.\nIf you do not need the flexibility of `mosaicview`, you can directly call the `MosaicView` constructor.\nThe remainder of this page illustrates the various options for `mosaic` and `mosaicview` and then covers the low-level `MosaicView` constructor.\n\n### More on the keyword options\n\n`mosaic` and `mosaicview` use almost all the same keyword arguments (all except `center`, which is not relevant for `mosaicview`).\nLet's illustrate some of the effects you can achieve.\nFirst, in the simplest case:\n\n```julia\njulia\u003e A1 = fill(1, 3, 1)\n3×1 Array{Int64,2}:\n 1\n 1\n 1\n\njulia\u003e A2 = fill(2, 1, 3)\n1×3 Array{Int64,2}:\n 2  2  2\n\n# A1 and A2 will be padded to the common size and shifted\n# to the center, this is a common operation to visualize\n# multiple images\njulia\u003e mosaic(A1, A2)\n6×3 MosaicView{Int64,4, ...}:\n 0  1  0\n 0  1  0\n 0  1  0\n 0  0  0\n 2  2  2\n 0  0  0\n```\n\nIf desired, you can disable the automatic centering:\n\n```julia\n# disable center shift\njulia\u003e mosaic(A1, A2; center=false)\n6×3 MosaicView{Int64,4, ...}:\n 1  0  0\n 1  0  0\n 1  0  0\n 2  2  2\n 0  0  0\n 0  0  0\n```\n\nYou can also control the placement of tiles. Here this is illustrated for `mosaicview`, but\nthe same options apply for `mosaic`:\n\n```julia\njulia\u003e A = [k for i in 1:2, j in 1:3, k in 1:5]\n2×3×5 Array{Int64,3}:\n[:, :, 1] =\n 1  1  1\n 1  1  1\n\n[:, :, 2] =\n 2  2  2\n 2  2  2\n\n[:, :, 3] =\n 3  3  3\n 3  3  3\n\n[:, :, 4] =\n 4  4  4\n 4  4  4\n\n[:, :, 5] =\n 5  5  5\n 5  5  5\n\n# number of tiles in column direction\njulia\u003e mosaicview(A, ncol=2)\n6×6 MosaicViews.MosaicView{Int64,4,...}:\n 1  1  1  4  4  4\n 1  1  1  4  4  4\n 2  2  2  5  5  5\n 2  2  2  5  5  5\n 3  3  3  0  0  0\n 3  3  3  0  0  0\n\n# number of tiles in row direction\njulia\u003e mosaicview(A, nrow=2)\n4×9 MosaicViews.MosaicView{Int64,4,...}:\n 1  1  1  3  3  3  5  5  5\n 1  1  1  3  3  3  5  5  5\n 2  2  2  4  4  4  0  0  0\n 2  2  2  4  4  4  0  0  0\n\n# take a row-major order, i.e., tile-wise permute\njulia\u003e mosaicview(A, nrow=2, rowmajor=true)\n4×9 MosaicViews.MosaicView{Int64,4,...}:\n 1  1  1  2  2  2  3  3  3\n 1  1  1  2  2  2  3  3  3\n 4  4  4  5  5  5  0  0  0\n 4  4  4  5  5  5  0  0  0\n\n# add empty padding space between adjacent mosaic tiles\njulia\u003e mosaicview(A, nrow=2, npad=1, rowmajor=true)\n5×11 MosaicViews.MosaicView{Int64,4,...}:\n 1  1  1  0  2  2  2  0  3  3  3\n 1  1  1  0  2  2  2  0  3  3  3\n 0  0  0  0  0  0  0  0  0  0  0\n 4  4  4  0  5  5  5  0  0  0  0\n 4  4  4  0  5  5  5  0  0  0  0\n\n# fill spaces with -1\njulia\u003e mosaicview(A, fillvalue=-1, nrow=2, npad=1, rowmajor=true)\n5×11 MosaicViews.MosaicView{Int64,4,...}:\n  1   1   1  -1   2   2   2  -1   3   3   3\n  1   1   1  -1   2   2   2  -1   3   3   3\n -1  -1  -1  -1  -1  -1  -1  -1  -1  -1  -1\n  4   4   4  -1   5   5   5  -1  -1  -1  -1\n  4   4   4  -1   5   5   5  -1  -1  -1  -1\n```\n\n### The `MosaicView` Type\n\nThe `MosaicView` constructor is simple and straightforward;\nif you need more layout options, consider calling it indirectly\nthrough `mosaicview`.\n\nThe layout of the mosaic is encoded in the third\n(and optionally fourth) dimension. Creating a `MosaicView` this\nway is type stable, non-copying, and should in general give\ndecent performance when accessed with `getindex`.\n\nLet us look at a couple examples to see the type in action. If\n`size(A)` is `(2,3,4)`, then the resulting `MosaicView` will have\nthe size `(2*4,3)` which is `(8,3)`.\n\n```julia\njulia\u003e A = [k for i in 1:2, j in 1:3, k in 1:4]\n2×3×4 Array{Int64,3}:\n[:, :, 1] =\n 1  1  1\n 1  1  1\n\n[:, :, 2] =\n 2  2  2\n 2  2  2\n\n[:, :, 3] =\n 3  3  3\n 3  3  3\n\n[:, :, 4] =\n 4  4  4\n 4  4  4\n\njulia\u003e MosaicView(A)\n8×3 MosaicViews.MosaicView{Int64,3,Array{Int64,3}}:\n 1  1  1\n 1  1  1\n 2  2  2\n 2  2  2\n 3  3  3\n 3  3  3\n 4  4  4\n 4  4  4\n```\n\nAlternatively, `A` is also allowed to have four dimensions. More\nconcretely, if `size(A)` is `(2,3,4,5)`, then the resulting size\nwill be `(2*4,3*5)` which is `(8,15)`. For the sake of brevity\nhere is a slightly smaller example:\n\n```julia\njulia\u003e A = [(k+1)*l-1 for i in 1:2, j in 1:3, k in 1:2, l in 1:2]\n2×3×2×2 Array{Int64,4}:\n[:, :, 1, 1] =\n 1  1  1\n 1  1  1\n\n[:, :, 2, 1] =\n 2  2  2\n 2  2  2\n\n[:, :, 1, 2] =\n 3  3  3\n 3  3  3\n\n[:, :, 2, 2] =\n 5  5  5\n 5  5  5\n\njulia\u003e MosaicView(A)\n4×6 MosaicViews.MosaicView{Int64,4,Array{Int64,4}}:\n 1  1  1  3  3  3\n 1  1  1  3  3  3\n 2  2  2  5  5  5\n 2  2  2  5  5  5\n```\n\n### Customizing promotion\n\nWhen the inputs are heterogeneous, `mosaic` attempts to convert the elements of all input arrays to a common type;\nif this promotion step throws an error, consider extending `MosaicViews.promote_wrapped_type` for your types.\n\n`ImageCore` provides such extensions for colors defined in [ColorTypes](https://github.com/JuliaGraphics/ColorTypes.jl).\nYou will likely want to load that package if you're using MosaicViews with `Colorant` arrays.\n(`ImageCore` gets loaded by nearly all the packages in the JuliaImages suite, so you may find that it is already loaded.)\n\n[travis-img]: https://travis-ci.org/JuliaArrays/MosaicViews.jl.svg?branch=master\n[travis-url]: https://travis-ci.org/JuliaArrays/MosaicViews.jl\n[codecov-img]: http://codecov.io/github/JuliaArrays/MosaicViews.jl/coverage.svg?branch=master\n[codecov-url]: http://codecov.io/github/JuliaArrays/MosaicViews.jl?branch=master\n[pkgeval-img]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/M/MosaicViews.svg\n[pkgeval-url]: https://juliaci.github.io/NanosoldierReports/pkgeval_badges/report.html\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuliaarrays%2Fmosaicviews.jl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjuliaarrays%2Fmosaicviews.jl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjuliaarrays%2Fmosaicviews.jl/lists"}