Convert ggplot2 graph to plotly - legend, labels and values

This works, but you may not like how it works. The issue with the tool tip only appearing on the line... bottom line, it's a ticket in Github.

This takes the legend, title, and subtitle from the ggplot object and adds them to the plotly object as an image. If you resize the image, you have to refresh, to get things aligned again.

library(tidyverse)
library(plotly)
library(magick) # for the legend and title
library(ggpubr) # for extracting the ggplot legend

# load data
# didn't include it--you obviously have your data
load("./_rdata/geosData.Rdata")

From here I created your ggplot object named rmurcia. The only element I changed was ggplot(), the rest is exactly as you originally designed it.

The revised ggplot():

rmurcia <- ggplot(data = geosmunicipios,
                  aes(text = paste('\nMunicipio: ', NOMBRE,
                                   '\nRenta Hogar 2016: ',
                                   format(Renta.media.por.hogar.2016, 
                                          big.mark=".", 
                                          decimal.mark=","), 
                                   "€",
                                   '\nRenta Hogar 2015: ', 
                                   format(Renta.media.por.hogar.2015, 
                                          big.mark = ".", 
                                          decimal.mark=","),
                                   "€",
                                   sep = ""),
                       color = Renta.media.por.hogar.2016.quantile)) +

and the rest of your code for this part.

Next, the legend:

#----------- the legend for plotly -------------
# instead of recreating your legend or title (matching font blocks, etc)

ggLegend = get_legend(rmurcia, position = "bottom")

as_ggplot(ggLegend)

# create a temp file to hold the image
temp <- tempfile(fileext = "png") 

# save plot legend as an image
ggsave(filename = temp, 
       plot = as_ggplot(ggLegend),
       device = "png",
       scale = 1,
       bg = "transparent")

# now read the png and convert to raster for plotly
imgr <- image_read(temp)

# take a look at the excessive whitespace that ggplot added 
image_border(image_background(imgr,
                              "hotpink"), 
             "#000080",
             ".1x.1") # you will have to scroll A LOT in the viewer pane

# remove this excess
(imgr <- image_trim(imgr))

# and convert to raster for plotly
imgrR <- as.raster(imgr)

# take a look to make sure it looks as expected
plot(imgrR)

# remove the tempfile
unlink(temp) 

Now for the title and subtitle:

#----------- the title for plotly -------------
# literally an empty graph with the title you originally specified
forTitle <- ggplot(data = geosmunicipios) + 
  theme_void() + 
  labs(title = "Región de Murcia",
       subtitle = "Renta media por hogar (2016)") + 
  theme(text = element_text(color = "#22211d"),
        plot.title = element_text(size= 22,
                                  hjust=0.5, 
                                  color = "#4e4d47", 
                                  margin = margin(b = -0.1,
                                                  t = 0.4,
                                                  l = 2, 
                                                  unit = "cm")),
        plot.subtitle = element_text(size= 17,
                                     hjust=0.5, 
                                     color = "#4e4d47", 
                                     margin = margin(b = -0.1,
                                                     t = 0.43,
                                                     l = 2, 
                                                     unit = "cm"))
  )

# create a temp file to hold the image
tmp <- tempfile(fileext = "png")

# save title plot as an image
ggsave(filename = tmp, 
       plot = forTitle,
       device = "png",
       scale = 1,
       bg = "transparent")

# now read the png 
imgr2 <- image_read(tmp)

# take a look at the excessive whitespace that ggplot added 
image_border(image_background(imgr2,
                              "hotpink"), 
             "#000080",
             ".1x.1") # you will have to scroll to the right

# remove this excess
(imgr2 <- image_trim(imgr2))

# and convert to raster for plotly
imgr2r <- as.raster(imgr2)

# take a look to make sure it looks as expected
plot(imgr2r)

# remove the tempfile
unlink(tmp) 

I do want to caveat to say that you could use "\n" and keep the title and subtitle together as the title. However, that keeps them the same font size. I thought that was ugly, so I came up with this approach. (Where there is a will, there is a way.)

Now for the plotly object...

#------------- now for plotly ---------------
ggplotly(rmurcia, 
         tooltip = "text") %>% 
  style(hoveron = "points+fills", # this isn't working,
                                  # currently a ticket in Github
        # this traces makes it so there is only one type of tooltip
        traces = seq.int(2,  
                         length(rmurcia$x$data))) %>%   
  hide_legend() %>%          # we aren't going to use the plotly legend
  layout(                    # remove the legend layout code
    title = list(text = ""), # remove the title
    images = list(
      list(source = raster2uri(imgrR), # the legend
           xref = "paper",
           yref = "paper",
           x = 0.32,       # x placement on the grid
           y = 0.03,       # y placement on the grid
           sizex = .4,     # scale to 40% of size width
           sizey = .4,     # scale to 40% of size height
           opacity = 1,
           layer = "above"),
      list(source = raster2uri(imgr2r), # the title/subtitle
           xref = "paper",
           yref = "paper",
           x = .23,       # x placement on the grid
           y = 1.09,      # y placement on the grid
           sizex = .55,   # scale to 55% of size width
           sizey = .55,   # scale to 55% of size height
           opacity = 1,
           layer = "above")
      # for controlling the plot size
    ), margin = list(l = 4, 
                     r = 40, 
                     b = 65, 
                     t = 65, 
                     pad = 4)
  )

I couldn't figure out a way to get rid of the black 'L', though I did try. You could add an image of white blocks to cover it, I suppose.

The sizes in the layout can change quite a bit, depending on the size of your plots/viewer pane. I would suggest choosing what you like best in ggplot and then work to adjust plotly from there. You will have to adjust the layout of the images if your ideal plot is a lot different dimensionally speaking.

As ggplot with export pixels of 608 wide by 661 high:

enter image description here

As plotly using same sized pane and the dimensions as in the code:

enter image description here

Almost forgot -- the tooltips:

enter image description here

I can tell you that the black 'L' in the plotly object is the basis for zooming in, panning, and all that.