arklumpus / TreeViewer

Cross-platform software to draw phylogenetic trees
GNU Affero General Public License v3.0
188 stars 9 forks source link

Export resized tree #11

Closed carlosmag closed 1 year ago

carlosmag commented 2 years ago

Hi! Is it possible to export a tree in a custom zoom (i.e. as shown in screen)?

Thanks in advance.

arklumpus commented 2 years ago

Hi! You can't do this directly; however, you have a few options:

  1. Export it as a PNG file and then crop it using something like Paint (or any image editing program). You can increase the DPI while exporting the image to have a bigger image to work with.
  2. Export it as an SVG (or PDF, but SVG is easier), and then crop it using something like Inkscape or Illustrator. For example, in Inkscape, you would:
    • Open the SVG file, select everything (CTRL+A) and create a group (CTRL+G). This creates a single object containing all the graphics elements.
    • Draw a rectangle over the area you want to highlight.
    • Select everything again (CTRL+A) and then do Object > Clip > Set (no keyboard shortcut for this ☹). This hides the parts of the plot that are outside of the rectangle.
    • Crop the image to the resulting area (CTRL+SHIFT+R).
  3. If you only want to plot a subtree, you can select the node and copy it in TreeViewer (there's a Copy button in the Edit tab, or you can just press CTRL+C), and then paste it again in TreeViewer (Paste button in the Edit tab, or just CTRL+V). This will open the subtree as if it were a new tree. Attributes that were set using further transformations are preserved (i.e., what you are copy/pasting is the "final transformed tree"), but all the plot elements are not, though you could use the Apply to other tree button to transfer them.

I would say that 2 is probably the best compromise between image quality and ease of use, as you still get a vector image. If you're creating PowerPoint slides or something like that, you could instead use 1 and just crop them within PowerPoint itself. If you haven't spent a lot of time fine-tuning the plot yet, 3 might be a viable approach too (also note that you can chop some nodes off using the Prune node module/button in the Selection action tab).

carlosmag commented 2 years ago

Thanks for all these tips!

Step 2) works great! However, SVG export (all modes) on TreeViewer is not preserving font aspect, which is highly inconvenient in my case.

PDF export seems to be the best alternative but I am having trouble in getting Inkscape to open pdfs on my system (possibly library issues).

Is there a way to make SVG to export fonts as PDF does?

arklumpus commented 2 years ago

If you select the Embed subsetted font or Embed full font options when exporting the SVG file, the fonts will actually be embedded in the SVG file (in fact, if you open it in a browser it will look OK); it's Inkscape that doesn't support fonts embedded in SVG files... However, if you open the file in Inkscape, do some changes (e.g. cropping), and then save it, Inkscape should preserve the embedded font, so that you can open again the file in a web browser and it will look OK.

If you use the Convert into paths option when exporting the SVG, the text should look OK even in Inkscape, but it won't be selectable/editable.

The only solution to that is to export the SVG with one of the options embedding the fonts, then selecting the text in Inkscape (select one text element and do Edit > Select same > Object type or SHIFT+ALT+A), enabling the text object and manually setting the font to a font that is installed on your computer (things like Arial or Helvetica should have the same metrics as the font used by default in TreeViewer).

But yeah, you convinced me - I will try to include a button to crop the exported tree to the current viewport in the next version of TreeViewer!

carlosmag commented 2 years ago

It seems that sK1 and LibreOffice Draw behave similarly to Inkscape. Nevertheless, exported SVG is shown correctly on browsers. I found I don't have Helvetica font installed on my Linux config, so maybe that's the issue...

I believe I found a workaround that's suited for my use case by 1) exporting tree as PDF -> open PDF with Krita -> use the rectangular selection tool and then click Image + Trim to selection -> export as TIFF -> import TIFF to Inkscape in order to join tree with other figures and perform adjustments...

Thanks for this useful info! Indeed, it's not the first time I have this problem with SVG and fonts...

EDIT: Curiously, I don't have problems with SVG files exported from R.

arklumpus commented 2 years ago

Yeah, font management in SVG is a bit of a nightmare: the standard allows for embedded fonts, but most editors expect you to only use fonts that are installed on your system...

By the way, "Helvetica" is just a placeholder for one of the 14 fonts defined in the PDF standard; a "metrics-compatible" version of these fonts is guaranteed to always be available in any PDF viewer, though the exact font may differ. Arial, Arimo, and Nimbus Sans L are examples of fonts with the same metrics as Helvetica. TreeViewer uses Nimbus Sans L (because of the GPL licence), but you should be able to replace it with any metrics-compatible alternative without huge differences.

I think you should be able to skip a step in your workaround if you just export the tree as a PNG (with a high enough resolution) with TreeViewer and then clip it in Inkscape - PNG and TIFF both use lossless conversion, so if you use the same resolution the results should be identical.

I have tried creating an SVG plot with R, and from what I see it does more or less the same thing as TreeViewer with the Convert into paths option - the text is converted into paths (though in a slightly fancier way). and thus it is not searchable or selectable.

carlosmag commented 2 years ago

I tried PNG before but had some issues related to DPI. Journals require 300 or 600 DPI images but the maximum DPI that I could get TreeViewer to export was 64. Higher than this value triggers Could not render image error.

In addition, even though image size seems to be big, DPI determined with identify -units PixelsPerInch -format '%[fx:int(resolution.x)]\n' treeviewer_alllabels.png is only 96.

Screenshot_20220606_165118

Maybe I can get around this by editing image metadata...

About R, I have been using ggplot2 package and SVG text is selectable on Inkscape...

arklumpus commented 2 years ago

Oh, I see! The issue is that the "dpi" you set when exporting the image is based on the size of the image as determined by the coordinates module, which is somewhat arbitrary... For example, the size of your plot appears to be about 9x9 metres. Trying to render an image this large at 300 dpi would create an image that is 100'000x100'000 pixels, which would require almost 10GB of (contiguous) RAM - hence the error.

To create an image with the correct DPI, you would first need to determine the size of the "printed" image (e.g., 17cm≈6.7in for an A4 sheet of paper with 2cm margins), then multiply that times the DPI to get the size in pixels (e.g. 6.7in*600dpi=4020 pixels) and finally enter that number as the width of the exported image. Of course, if you are only interested in a subset of the image, you would have to increase the resolution accordingly (e.g., if you want half of the image to be 17cm wide at 600dpi, the correct width would be 8040 pixels), so things may get a bit complicated.

The 96 DPI you get is just the default value for a PNG image, as TreeViewer does not set the metadata when exporting the PNG.

In any case, I think I have a couple of ideas on how to address this, so hopefully it should be more intuitive in the next version (and the correct metadata will be set). I am reopening this in order to keep track of the issue.

In R, are you creating the SVG device using svglite? In that case, it appears that text is indeed selectable, but it is drawn using a system font (e.g. DejaVu Sans). That will be OK if you only open the file on the computer where you created the file (or if you later export the image as PDF or raster), but if you open the SVG file on another machine the text might look different (especially if you move it e.g. from a machine running Linux to one running Windows or macOS).

carlosmag commented 2 years ago

Thanks for the PNG tips! It would be nice to have a more straightforward manner to deal with DPIs.

In R, I am using the Export button on the Plots tab of RStudio. I am not sure which device is being used...

arklumpus commented 1 year ago

Hi, I have finally added a new module and a few options to specify "crop regions" and to properly set up the output DPI! You can find these in TreeViewer 2.1.0.

There is a tutorial in the wiki showing how to use these, let me know if everything is clear!

I am closing this, but feel free to reopen or to open a new issue if you still have questions!