juliaijulia-notebook

ProgressBar in IJulia printing every new line


I am currently learning Julia and have been practicing in the Jupyter notebook environment. However, the ProgressBar package (similar to TQDM in python) is updated every new line instead of updating on the same line (picture attached). Is there any way to fix this? Thanks.

UPDATE : Here is the full function that I wrote.

function spike_rate(raw_dat, width)

    N = size(raw_dat)[1]
    domain = collect(1:N);
    spike_rat = zeros(N);

    for i in ProgressBar(1:N)
        dx = i .- domain;
        window = gaussian.(dx, width);
        spike_rat[i] = sum(window .* raw_dat) ./ width;
    end

    return spike_rat;

end

enter image description here


Solution

  • This seems to be a known issue with ProgressBars.jl, unfortunately. It's not clear what changed to make these progress bars not work properly anymore, but the maintainer's comment says that tqdm uses "a custom ipywidget" to make this work for the Python library, and that hasn't been implemented for the Julia package yet.

    To expand on @Zitzero's mention of ] up, that calls Pkg.update() which also prints a progress bar - so the suggestion is to use the mechanism Pkg uses for it. Pkg has an internal module called MiniProgressBars which handles this output.


    Edit: Tim Holy's ProgressMeter package seems well-maintained, and is a much better option than relying on an internal non-exported Pkg submodule with no docs. So I'd recommend ProgressMeter over the below.

    The Readme mentions a caveat regarding printing additional information with the progress bar when in Jupyter, which likely applies to MiniProgressBar as well. So, using ProgressMeter, and separating the progress output vs other relevant output to different cells, seems like the best option.


    (not recommended)

    using Pkg.MiniProgressBars
    
    bar = MiniProgressBar(; indent=2, header = "Progress", color = Base.info_color(),
                                  percentage=false, always_reprint=true)
    bar.max = 100
    
    # start_progress(stdout, bar)
    for i in 1:100
        sleep(0.05) # replace this with your code
        # print_progress_bottom(stdout)
        bar.current = i 
        show_progress(stdout, bar)
    end
    # end_progress(stdout, bar)
    

    This is based on how Pkg uses it, from this file. The commented out lines (with start_progress, print_progress_bottom, and end_progress) are in the original usage in Pkg, but it's not clear what they do and here they just seem to mess up the output - maybe I'm using them wrongly, or maybe Jupyter notebooks only support a subset of the ANSI codes that MiniProgressBars uses.