2
votes

I want to compare the distribution of several dimensions of technologization using violin plots (the dimensions are measured by indices ranging from 1 to 5). 5 out of 6 violin plots look as you would expect, but one has a really odd shape that isn't reflected in the data. So I wonder if there is any explanation for that. I will show you the tables of the variables, the code I used to create the plot and the plot itself. If you need more information, feel free to ask.

The tables:

> table(dat$cps_an, useNA="ifany")   # CPS-Anlagen

                0             0.625 0.833333333333333              1.25  1.66666666666667             1.875               2.5             3.125              3.75             4.375 
               22                21                 3                20                 4                18                19                15                 5                 1 
                5              <NA> 
                2                 5 
> table(dat$cps_prod, useNA="ifany")   # CPS-Produkte

                0             0.625 0.833333333333333              1.25  1.66666666666667             1.875               2.5             3.125  3.33333333333333              3.75 
                3                 8                 1                28                 3                33                38                13                 3                 3 
            4.375 
                2 
> table(dat$cpps, useNA="ifany")   # Produktionssysteme

                0 0.333333333333333                 1  1.16666666666667               1.5              1.75                 2               2.5  2.66666666666667  2.83333333333333 
                2                 1                 2                 2                 1                 1                11                 3                 2                 9 
                3  3.16666666666667  3.33333333333333               3.5  3.66666666666667              3.75  3.83333333333333  4.16666666666667  4.33333333333333  4.66666666666667 
                9                 2                22                 1                 3                 2                 9                28                 1                 6 
                5              <NA> 
               13                 5 
> table(dat$mobile, useNA="ifany")   # Mobile Devices

               0 1.66666666666667              2.5 3.33333333333333             3.75 4.16666666666667                5 
               3               29                4                2                3               34               60 
> table(dat$strat, useNA="ifany")   # Strategie und Organisation

               0            0.625             1.25 1.66666666666667            1.875              2.5            3.125 3.33333333333333             3.75            4.375                5 
               1                3                3                2               11               34               38                3               11                8                5 
            <NA> 
              16 
> table(dat$index, useNA="ifany")   # Gesamt-Index

0.485416666666667             0.975  1.25104166666667           1.30625  1.31979166666667  1.33958333333333  1.82604166666667  1.86041666666667  1.93854166666667  2.00416666666667 
                1                 1                 1                 1                 1                 1                 1                 1                 1                 1 
 2.04791666666667  2.06354166666667  2.15104166666667  2.16666666666667            2.1875          2.203125  2.23541666666667  2.26041666666667  2.30104166666667          2.303125 
                1                 1                 1                 2                 1                 1                 1                 1                 1                 1 
 2.31666666666667  2.33854166666667          2.353125  2.36041666666667  2.38541666666667          2.390625  2.39479166666667          2.415625  2.43854166666667          2.453125 
                2                 1                 1                 1                 1                 1                 1                 1                 1                 1 
 2.47916666666667  2.54479166666667            2.5625           2.56875          2.584375  2.58854166666667  2.60416666666667  2.62604166666667           2.65625          2.671875 
                1                 1                 1                 1                 1                 1                 1                 1                 1                 2 
           2.6875  2.69166666666667  2.70416666666667          2.728125              2.75           2.75625  2.78541666666667  2.81354166666667          2.828125           2.84375 
                1                 1                 1                 1                 1                 1                 1                 1                 1                 1 
          2.86875  2.86979166666667             2.875  2.88541666666667            2.9125  2.91666666666667  2.94270833333333          2.953125  2.95833333333333          2.959375 
                1                 1                 1                 1                 1                 1                 1                 1                 1                 1 
 2.96354166666667           2.96875          2.984375  2.99791666666667          3.015625           3.03125  3.03541666666667          3.046875  3.05104166666667  3.05729166666667 
                1                 1                 1                 1                 1                 3                 1                 2                 1                 1 
         3.078125  3.07916666666667  3.08854166666667           3.09375  3.11666666666667             3.125          3.140625  3.16979166666667  3.17604166666667            3.1875 
                1                 1                 1                 1                 1                 2                 1                 1                 1                 1 
         3.209375            3.2125          3.228125              3.25  3.26041666666667          3.290625          3.296875           3.30625  3.32291666666667          3.328125 
                1                 1                 1                 1                 1                 1                 1                 1                 1                 1 
            3.375  3.43229166666667  3.44791666666667  3.47916666666667  3.58854166666667  3.64166666666667  3.72291666666667  3.80104166666667          3.859375  3.96354166666667 
                2                 2                 1                 1                 1                 1                 1                 1                 1                 1 
         3.984375  4.15833333333333            4.1875           4.30625              <NA> 
                1                 1                 1                 1                22 

The code for the violin plots:

technologie_df <- data.frame(group=c(rep("CPS: Anlagen", nrow(dat)),
                                     rep("CPS: Produkte", nrow(dat)),
                                     rep("Produktionssysteme", nrow(dat)),
                                     rep("Mobile Devices", nrow(dat)),
                                     rep("Strategie und Organisation", nrow(dat)),
                                     rep("Gesamt-Index", nrow(dat))),
                             value=c(dat$cps_an, dat$cps_prod, dat$cpps, dat$mobile, dat$strat, dat$index))
technologie_df <- na.omit(technologie_df)

technologie_plot <- ggplot(technologie_df, aes(x=group, y=value, fill=group)) +
  geom_violin() +
  labs(y="Index-Wert") +
  scale_x_discrete(limits=c("CPS: Anlagen", "CPS: Produkte", "Produktionssysteme", "Mobile Devices", "Strategie und Organisation", "Gesamt-Index")) +
  scale_fill_manual(values=c("#003560","#8DAE10","#8DAE10","#8DAE10","#003560","#003560")) +
  theme(axis.title.x = element_blank(),
        panel.background = element_blank(),
        axis.line = element_line(colour="black"),
        legend.position = "none")
ggsave(file.path(path_out,"ViolinPlot_Technologie.png"), plot=technologie_plot, type="cairo-png")

And the plot itself:

Violin plots

The plot that irritates me of course is the one of "Strategie und Organisation" as its shape doesn't fit the data. If you look at the table, there are 34 people with a rating of 2.5 and 38 people with a rating of 3.125. There is no value in between that has fewer people who might explain the gap between 2.5 and 3.125 in the plot. The same goes for most of the other gaps. The other plots don't have these gaps. Is there an explanation for this?

1
The 5th violin probably has discrete data and my suggestion is to increase the bandwidth of the kernel density estimation part, i.e. geom_violin(..., adjust = 2)teunbrand
Your data is highly discretized, so density curves often suffer depending on the kernel-width used for the density. Changing the kernel width will help smooth that out a bit. In ?geom_violin, it suggests reading ?density for kernel options. (BTW, giving us a table(...) of your data is really not good, it is much better to just use dput for the whole frame.)r2evans
BTW, your method of converting from wide to long format is creative but perhaps more prone to user error. Alternatives (that are more flexible if you have anything else) include: tidyr::pivot_longer(dat, everything(), names_to = "group", values_to = "value") and data.table::melt(data.table::as.data.table(dat), variable.name = "group"). In this case it does the same thing you're doing, but without having to recode if/when you add/remove columns and/or change their order.r2evans
The approach to change the adjust option worked. Thank you very much. I will also try out the alternative conversion style.Julius Kötter
if you got the solution from @r2evans's comments, I'd encourage you to post an answer (you have to wait a few hours to self-answer, I think; this also lets commenters post their comments as answer if they feel like it)Ben Bolker

1 Answers

2
votes

If you want your violin plot to highlight the discrete nature of the data, you can set adjust within the geom_violin() to a small value:

ggplot(dat) +
  geom_violin(aes(x = "Strategie und Organisation", y = strat), adjust = 0.1)

enter image description here

If you want the plot to hide the discrete nature of the data, set adjust to a larger value.

ggplot(dat) +
  geom_violin(aes(x = "Strategie und Organisation", y = strat), adjust = 1.5)

enter image description here

Here is the data based on the OP's post.

dat <- data.frame(strat = c(0, rep(0.625, 3), 
                          rep(1.25, 3), 
                          rep(5/3, 2), 
                          rep(1.875, 11),
                          rep(2.5, 34),
                          rep(10/3, 3),
                          rep(3.75, 11),
                          rep(4.375, 8),
                          rep(5, 5)))