diff --git a/README.md b/README.md index c1ae5e3..9516078 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# [WordCloud.jl](https://github.com/guo-yong-zhi/WordCloud.jl) +#
[WordCloud.jl](https://github.com/guo-yong-zhi/WordCloud.jl)
![juliadoc](res/juliadoc.png) [![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://guo-yong-zhi.github.io/WordCloud.jl/dev) [![Binder](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/guo-yong-zhi/WordCloud.jl/master?filepath=examples.ipynb) [![CI](https://github.com/guo-yong-zhi/WordCloud.jl/actions/workflows/ci.yml/badge.svg)](https://github.com/guo-yong-zhi/WordCloud.jl/actions/workflows/ci.yml) [![CI-nightly](https://github.com/guo-yong-zhi/WordCloud.jl/actions/workflows/ci-nightly.yml/badge.svg)](https://github.com/guo-yong-zhi/WordCloud.jl/actions/workflows/ci-nightly.yml) [![codecov](https://codecov.io/gh/guo-yong-zhi/WordCloud.jl/branch/master/graph/badge.svg?token=2U0X769Z51)](https://codecov.io/gh/guo-yong-zhi/WordCloud.jl) Word cloud (tag cloud or wordle) is a novelty visual representation of text data. The importance of each word is shown with font size or color. Our generator has the following highlights: @@ -51,7 +51,7 @@ paint(wc, "alice.png", ratio=0.5, background=outline(wc.mask, color="purple", li *Run the command `runexample(:recolor)` or `showexample(:recolor)` to get the result.* ## Semantic [![semantic](res/semantic.png)](./examples/semantic.jl) -*Run the command `runexample(:semantic)` or `showexample(:semantic)` to get the result.* +*Run the command `runexample(:semantic)` or `showexample(:semantic)` to get the result.* *The variable `WordCloud.examples` holds all available examples.* You can also [**see more examples**](https://github.com/guo-yong-zhi/WordCloud-Gallery) or [**try it online**](https://mybinder.org/v2/gh/guo-yong-zhi/WordCloud.jl/master?filepath=examples.ipynb). # Algorithm Description diff --git a/docs/make.jl b/docs/make.jl index e0cd8b5..53fca30 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -7,7 +7,7 @@ Documenter.makedocs( modules = Module[WordCloud], repo = "", highlightsig = true, - sitename = "WordCloud Documentation", + sitename = "WordCloud.jl", expandfirst = [], pages = [ "Index" => "index.md", diff --git a/docs/src/assets/logo.svg b/docs/src/assets/logo.svg new file mode 100644 index 0000000..cd07a05 --- /dev/null +++ b/docs/src/assets/logo.svg @@ -0,0 +1,135 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/src/index.md b/docs/src/index.md index cc5564f..6cdee6b 100644 --- a/docs/src/index.md +++ b/docs/src/index.md @@ -21,7 +21,9 @@ Pkg.add("WordCloud") Modules = [WordCloud] ``` -## Index +## Gallery +* [WordCloud-Gallery](https://github.com/guo-yong-zhi/WordCloud-Gallery) +## Index ```@index ``` diff --git a/examples/logo.jl b/examples/logo.jl new file mode 100644 index 0000000..1bdcd25 --- /dev/null +++ b/examples/logo.jl @@ -0,0 +1,36 @@ +#md# It is the code to draw this repo's logo +using WordCloud +Luxor = WordCloud.Render.Luxor + +function cloudshape(height, args...; backgroundcolor=(0,0,0,0)) + height = ceil(height) + r = height / 2 + d = Luxor.Drawing((2height, height)..., :svg) + Luxor.origin() + Luxor.background(parsecolor(backgroundcolor)) + Luxor.setcolor(parsecolor((0.22,0.596,0.149))) + Luxor.pie(0, 0, r, 0, 2π, :fill) + Luxor.setcolor(parsecolor((0.584,0.345,0.698))) + Luxor.pie(r, r, r, -π, 0, :fill) + Luxor.setcolor(parsecolor((0.796,0.235,0.20))) + Luxor.Luxor.pie(-r, r, r, -π, 0, :fill) + Luxor.finish() + d +end +wc = wordcloud( + repeat(string.('a':'z'), 5), + repeat([1], 26*5), + mask = cloudshape(500), + transparent = (0,0,0,0), + colors = 1, + angles = -90:0, + font = "JuliaMono Black", + density=0.77, + ) +generate!(wc, 2000, retry=1) +recolor!(wc, style=:main) +println("results are saved to logo.svg") +paint(wc, "logo.svg", background=false) +wc +#eval# runexample(:logo) +#md# ![](logo.svg) \ No newline at end of file diff --git a/src/artist.jl b/src/artist.jl index db186d0..c50d785 100644 --- a/src/artist.jl +++ b/src/artist.jl @@ -119,7 +119,7 @@ function randomellipse(w, h; kargs...) return shape(ellipse, w, h; kargs...) end function randomangles() - a = rand((-1, 1)) .* rand((0, (0,90), (0,90,45), (0,90,45,-45), (0,45,-45), (45,-45), -90:90)) + a = rand((-1, 1)) .* rand((0, (0,90), (0,90,45), (0,90,45,-45), (0,45,-45), (45,-45), -90:90, 0:90)) println("angles = ", a) a end diff --git a/src/textprocessing.jl b/src/textprocessing.jl index be0cb55..57f4ad1 100644 --- a/src/textprocessing.jl +++ b/src/textprocessing.jl @@ -48,10 +48,10 @@ function countwords(words::AbstractVector{<:AbstractString}; m = match(regexp, w) if m !== nothing w = m.match - counter[w] = get!(counter, w, 0) + 1 + counter[w] = get(counter, w, 0) + 1 end else - counter[w] = get!(counter, w, 0) + 1 + counter[w] = get(counter, w, 0) + 1 end end counter diff --git a/src/wc-method.jl b/src/wc-method.jl index 1de8c3b..1125c16 100644 --- a/src/wc-method.jl +++ b/src/wc-method.jl @@ -115,9 +115,29 @@ end recolor_reset!(wc, i::Integer) = initword!(wc, i) recolor_reset!(wc, w=:; kargs...) = recolor_reset!.(wc, index(wc, w); kargs...) - +function counter(iter; C = Dict{eltype(iter), Int}()) + for e in iter + C[e] = get(C, e, 0) + 1 + end + C +end +function mostfrequent(iter; C = Dict{eltype(iter), Int}()) + C = counter(iter; C = C) + argmax(C) +end +function recolor_main!(wc, i::Integer; background=getmask(wc)) + bg = ARGB.(background) + img = getimages(wc, i) + x,y = getpositions(wc, i) + bg, img = Render.overlappingarea(bg, img, x, y) + m = wordmask(img, (0,0,0,0),0) + bkv = @view bg[m] + c = mostfrequent(bkv) + initword!(wc, i, color=c) +end +recolor_main!(wc, w=:; kargs...) = recolor_main!.(wc, index(wc, w); kargs...) function recolor_average!(wc, i::Integer; background=getmask(wc)) - bg = background + bg = ARGB.(background) img = getimages(wc, i) x,y = getpositions(wc, i) bg, img = Render.overlappingarea(bg, img, x, y) @@ -157,19 +177,22 @@ end recolor_clipping!(wc, w=:; kargs...) = recolor_clipping!.(wc, index(wc, w); kargs...) """ recolor the words in `wc` in different styles with the background picture. -The styles supported are `:average`, `:clipping`, `:blending`, and :reset (to undo all effects of others). +The styles supported are `:average`, `:main`, `:clipping`, `:blending`, and :reset (to undo all effects of others). e.g. -* recolor!(wc, style=:average) # `background` is optional +* recolor!(wc, style=:average) +* recolor!(wc, style=:mian) * recolor!(wc, style=:clipping, background=blur(getmask(wc))) # `background` is optional * recolor!(wc, style=:blending, alpha=0.3) # `background` and `alpha` are optional * recolor!(wc, style=:reset) -The effects of `:average` and `:clipping` are only determined by the `background`. But the effect of `:blending` is also affected by the previous word color. Therefore, `:blending` can also be used in combination with others +The effects of `:average`, `:main` and `:clipping` are only determined by the `background`. But the effect of `:blending` is also affected by the previous word color. Therefore, `:blending` can also be used in combination with others The results of `clipping` and `blending` can not be exported as SVG files, use PNG instead. """ function recolor!(wc, args...; style=:average, kargs...) if style == :average recolor_average!(wc, args...; kargs...) + elseif style == :main + recolor_main!(wc, args...; kargs...) elseif style == :blending recolor_blending!(wc, args...; kargs...) elseif style == :clipping diff --git a/test/Manifest.toml b/test/Manifest.toml deleted file mode 100644 index ac58105..0000000 --- a/test/Manifest.toml +++ /dev/null @@ -1,33 +0,0 @@ -# This file is machine-generated - editing it directly is not advised - -[[Base64]] -uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f" - -[[Distributed]] -deps = ["Random", "Serialization", "Sockets"] -uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b" - -[[InteractiveUtils]] -deps = ["Markdown"] -uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240" - -[[Logging]] -uuid = "56ddb016-857b-54e1-b83d-db4d58db5568" - -[[Markdown]] -deps = ["Base64"] -uuid = "d6f4376e-aef5-505a-96c1-9c027394607a" - -[[Random]] -deps = ["Serialization"] -uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" - -[[Serialization]] -uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" - -[[Sockets]] -uuid = "6462fe0b-24de-5631-8697-dd941f90decc" - -[[Test]] -deps = ["Distributed", "InteractiveUtils", "Logging", "Random"] -uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"