Typo in code has been fixed so that it should now be reproducible
I am new to posting on StackOverflow so please let me know should my question or example not be clear enough and I will add more information as needed.
I am trying to develop a forest plot in R using plotly. For this, I need to be able to position the text along the y axis as if it were a formatted table (column content should be left-aligned for text, right-aligned for numbers, see here for an example).
My initial solution was to have one, long, formatted string per y axis tick (using print formatting). This works, but only for monospaced font.
So now I am trying to use annotations instead of y axis labels. The difficulty lies in placing each annotation/column correctly outside the plotting area to created the desired formatting. I first wanted to find the widest string in a column and to calculate the normalized coordinates accordingly, but I am not experienced in this so although I could get the annotations to show up as left-aligned columns, my conversions were wrong and the spaces between the columns were large. Here is what I used to try and figure out the coordinates. If you can point me towards other functions for this or know how I can work with these coordinates, this would definitely be my preferred solution. Note that the number of columns to be plotted to the left/right of the plot will be selected dynamically by the user, and so the plot's margins also need to be able to adjust. And I believe those have to be provided in pixels, so this brings along another conversion, from normalized coordinates to pixels...
longestMpg = max(strwidth(mtcars$mpg, unit = 'in'))
coord = grconvertX(longestMpg, from = 'inches', to = 'ndc') #normalized device coordinates
# coord = grconvertX(longestNames, from = 'inches', to = 'npc') # normalized plot coordinates
# coord = grconvertX(longestNames, from = 'inches', to = 'nfc') # normalized figure coordinates
So now I have moved on to placing each column/annotation into a separate plot at x = 0 and to trying to combine them into one subplot at the end (not a very elegant workaround...). The problem here is that the text shows up left-aligned for each plot separately (I am not trying to mix left-aligned and right-aligned text at this point), but as soon as I put both plots into one subplot, the text in the second plot is center-aligned. Here is a very simple example:
library(plotly)
# Plot only mtcar$disp
aPlot = plotly_empty(mtcars, type = "scatter", mode = "markers") %>%
config(
displayModeBar = FALSE
)
for (i in 1:nrow(mtcars)) {
aPlot = aPlot %>% add_annotations(x = 0,
y = i,
text = mtcars$disp[i],
xref = 'paper',
yref = 'y',
showarrow = F) %>%
layout(yxaxis = list(showline = T), yaxis = list(showline = T))
}
# Plot only mtcar rownames
bPlot = plotly_empty(mtcars, type = "scatter", mode = "markers") %>%
config(
displayModeBar = FALSE
)
for (i in 1:nrow(mtcars)) {
bPlot = bPlot %>% add_annotations(x = 0,
y = i,
text = rownames(mtcars)[i],
xref = 'paper',
yref = 'y',
showarrow = F) %>%
layout(yxaxis = list(showline = T), yaxis = list(showline = T))
}
# Subplot
subplot(aPlot, bPlot, shareX = T, shareY = F)
Maybe there is an easier, more elegant way to achieve what I am looking for and I am happy to learn something new so please don't hesitate to share your ideas. Grateful for any help!