[ANN] Fatou.jl : Easily share Julia fractals

Maybe off topic but I am unable to install it in 1.0.1. It fails with following error

(v1.0) pkg> add Fatou
  Updating registry at `~/.julia/registries/General`
  Updating git-repo `https://github.com/JuliaRegistries/General.git`
 Resolving package versions...
ERROR: Unsatisfiable requirements detected for package Fatou [5f923234]:
 Fatou [5f923234] log:
 ├─possible versions are: [0.0.1-0.0.3, 0.1.0-0.1.3, 0.2.0, 1.0.0] or uninstalled
 ├─restricted to versions * by an explicit requirement, leaving only versions [0.0.1-0.0.3, 0.1.0-0.1.3, 0.2.0, 1.0.0]
 └─restricted by julia compatibility requirements to versions: uninstalled — no versions left

Not sure what is the cause of that. Have you tried with dev Fatou instead?

dev Fatou works. I checked the metadata repo and it was updated there so I didn’t know what has caused the error in my previous message.

This is an announcement update, Fatou version 1.0.1 has been released, which now has a significant performance improvement due to the suggestion by @ckoe-bccms with parametric types

This should fix the issue with the high memory allocation for large n, allowing bigger fractals, faster

julia> newton(:(z^3-1);n=3500)|>fatou;
  1.004239 seconds (541 allocations: 36.706 KiB)

The testing behavior of the package is a bit weird on some platforms, but with PyPlot, it should work.

Out of curiosity, what was the timing before type parameters, for running that code?

In this post, I had a comparison of n=1500 grid, which took 19 seconds before, while only taking 0.17 seconds in the new version with the parametric types.

It’s probably due to assigning the Fatou.Define object to parallel threads, because the iteration function depends on two Bool values in that object and also functions in it, which might become unnecessary now due to the information provided by the parametric type. Now, only the complex number is variable.

1 Like

This here is a fractal which is notoriously difficult to calculate, now it can be calculated at higher resolution

newton(:(z^(4.0+3.0im)-1),m=2.1,∂=π,n=2000,N=27,cmap="terrain") |> fatou |> plot
 13.986463 seconds (541 allocations: 36.706 KiB)

With these improvements, it still takes 14 seconds for 2000 pixels, but previously 500 pixels was reasonable

complex-fractal

That is using N=27 iterations maximum. This one is a slow fractal to compute. Post some more fractals!

2 Likes

The newly tagged release of Fatou enables support for ImageInTerminal and deprecates the requirement for having PyPlot on your Julia installation. However, it continues to support PyPlot if it is installed.

Here’s what ImageInTerminal looks like with some Fatou.FilledSet displayed.

If you want your favorite plotting program to be compatible, you are welcome to make a PR

5 Likes

I mean you could implement the plotting with recipes instead. All that is needed is RecipesBase, which is 200 loc with zero dependencies and no exports, and then the user would need Plots to plot it.
There are lots of colormaps available: Colors · Plots
If the color gradients from matplotlib can be made available within the MIT license here we would be happy to take a PR adding them so that this functionality becomes available. But - the jet, cubehelix and gist_earth color schemes are not perceptually uniform. Why do you choose this set of palettes?

2 Likes

To summarize, the reason why I used PyPlot is because it has lots of nice color maps, that’s why I made the package specifically compatible with PyPlot and not Plots, but anyone is welcome to add Plots support.

RecipesBase looks interesting, perhaps I will add that feature soon

I choose those color schemes on purpose, because I think they look the most interesting for fractals.

Some of them like jet,cubehelix are already available with ColorSchemes, but gist_earth is not available yet. The ColorSchemes can be used for ImageInTerminal, while the matplotlib are used for PyPlot. A large amount of them are compatible, but not all of them. I would like to see more also.

Great! I can see your colours do look interesting for fractals. If you do attempt to write recipes I think we could put those three in the misc library

I can easily add new schemes to ColorSchemes.jl, I just ran out of ideas for new ones… :slight_smile:

1 Like

Could you add the missing ones from here https://matplotlib.org/examples/color/colormaps_reference.html

For example, such as ocean, gist_earth, gnuplot which are all missing, then color maps will be much more portable across different plotting environments.

I can add them tomorrow, but it will be easier if I can find the actual color definitions somewhere, rather than just the swatches.

This page has more information https://matplotlib.org/tutorials/colors/colormaps.html

and also here https://matplotlib.org/tutorials/colors/colormap-manipulation.html

You can define your own colour maps in Plots.jl IIRC. Or let the user do it themselves?

1 Like

Yes, I’ve always had plans to make the color maps in Fatou independent of PyPlot, which can be solved with the use of ColorSchemes package. Unfortunately, I’ve not had the time to prioritize this.

The interface will generalize, please share if you have any specific interface example in mind.

The problem with ColorSchemes is that it’s a package with a big list of heavy dependencies, which is unneccesary for just providing color schemes (but useful for doing the other things you can do here). @cormullion maybe we should make that dependency-free ColorMaps package that simply holds color swatches, uses submodules to hold different libraries, and can be depended on by Colors, ColorSchemes, PlotUtils, Makie etc.?
We could ask some of the other libraries like colorbrewer.jl and noveltycolors and perceptualcolormaps to just put swatches in there (or basic functions describing the rgb curves if that’s preferred) so that we consolidate colorschemes in Julia.

2 Likes

Sounds like a good idea ( :slight_smile: ). Perhaps the dependency on Images.jl could be transferred to a ...Utils package.

While converting the ones in https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/_cm.py I skipped a few, mainly the ones with lambdas in them (since I don’t speak Python, I’m not sure what these lambdas are doing).

_flag_data = {
        'red': lambda x: 0.75 * np.sin((x * 31.5 + 0.25) * np.pi) + 0.5,
        'green': lambda x: np.sin(x * 31.5 * np.pi),
        'blue': lambda x: 0.75 * np.sin((x * 31.5 - 0.25) * np.pi) + 0.5,
}

which generates this (obviously very useful):