I think a bipartite graph can meet your need.
First, you need to move the rowname to the first column, convert it to the data frame and change it to a long table. I also exclude rows with values "0".
library(dplyr)
df <- cbind(Name = rownames(data), data) %>%
as.data.frame() %>%
pivot_longer(!Name, names_to = "Plan", values_to = "n") %>%
mutate(n = as.numeric(n)) %>%
filter(n > 0)
Use the package called bipartiteD3 to create the chart. But I want to sort the chart based on the 'n' to make the chart even more attractive.
SortPrim <- df %>% # Sorting for the first column (Name)
group_by(Name) %>%
summarise(Total=sum(n))%>%
arrange(desc(Total))
SortSec <- df %>% # Sorting for the second column (Plan)
group_by(Plan) %>%
summarise(Total=sum(n))%>%
arrange(desc(Total))
The chart created below can be further adjusted to meet your preference. I have set it to 'vertical' because it's a very long list. If you prefer a horizontal chart, as you provided in your question, you should change details from line 10. I still prefer the vertical version though. Read the documentation to make further adjustments.
library(bipartiteD3)
bipartite_D3(df, colouroption = 'brewer',
Orientation = 'vertical',
ColourBy = 1,
PercentageDecimals=1,
PrimaryLab = 'Plan',
SecondaryLab = 'name',
SiteNames = '',
SortPrimary = SortPrim$Plan,
SortSecondary = SortSec$Name,
MainFigSize = c(500, 3600),
IndivFigSize = c(200, 1300),
BoxLabPos = c(20, 20),
PercPos = c(110,110),
BarSize = 20,
MinWidth = 10,
Pad=8,
filename = 'Plot')