Saving all plots from a ROOT file into separate png files

I have a ROOT file which contains several plots. I want to save all of them to separate png files, replicating the directory structure that is within the ROOT file as well. How can I do this? I am trying with rootprint like this:

rootprint 01_mask_noisy_pixels.root -d 01_mask_noisy_pixels -f png

After running, without errors or warnings, the 01_mask_noisy_pixels directory is empty.


can you do

rootls 01_mask_noisy_pixels.root

and paste here the output?

Hi, I get this:

$ rootls 01_mask_noisy_pixels.root 
EventLoaderEUDAQ2  MaskCreator

Inside those two “root folders” there are more “folders” with plots. This is what I want to “extract”. In case I am not expressing myself clearly, this:

It seems you’ll need the -d option but you will need to specify the whole path. there is no “recursive option”

What do you mean with that? This rootprint 01_mask_noisy_pixels.root -d /home/myself/test_beam/01_mask_noisy_pixels -f png? It does the same.

sorry, I miss-read the help -d is a directory where to put the output pictures.

It looks to me like rootprint does not know how to handle files where all histograms are located in a top-level “folder”. I have a file without “folder”, for which rootprint successfully produces .png files, and a file with a “folder” - indeed, nothing happens for it.

Is there any workaround? I am not an experienced ROOT user, I just need to be able to explore these plots as individual files. The reason: I am SSHing into the PC where the ROOT files are, and if I want to see the plots as it is now I either transfer the full ROOT file to my local PC, which takes considerable time, or I open ROOT remotely with SSH, which is considerably slow. So I just want to have the plots as normal files.

Try this tutorial, maybe it helps you: ROOT: tutorials/io/loopdir.C File Reference

see also Saving All Graphs as PNG Files - #5 by sbinet

I opened rootprint missing recursive traversal · Issue #13659 · root-project/root · GitHub

groot’s root-print (it’s now under doesn’t output files in a hierarchical fashion (even though it does walk through the whole internal ROOT file directory structure).

walking the contents of a ROOT file is relatively easy though:

package main

import (

	stdpath "path"


func main() {
	f, err := riofs.Open("../testdata/dirs-6.14.00.root")
	if err != nil {
	defer f.Close()

	fmt.Printf("visit all ROOT file tree:\n")
	err = riofs.Walk(f, func(path string, obj root.Object, err error) error {
		fmt.Printf("%s (%s)\n", path, obj.Class())
		return nil
	if err != nil {
		log.Fatalf("could not walk through file: %v", err)

with the following output:

visit all ROOT file tree:
dirs-6.14.00.root (TFile)
dirs-6.14.00.root/dir1 (TDirectoryFile)
dirs-6.14.00.root/dir1/dir11 (TDirectoryFile)
dirs-6.14.00.root/dir1/dir11/h1 (TH1F)
dirs-6.14.00.root/dir2 (TDirectoryFile)
dirs-6.14.00.root/dir3 (TDirectoryFile)