Below is a code that works using the plot() function to run a 2D scatterplot of Height vs Weight where points are classed as “Good”, “Fair”, “Poor” based on whether the Class value is 1, 2 or 3, respectively. Points for "Good" are bright green, "Fair", olive green and Poor, red. All points are the same size (pch=19). Is it possible to have different sizes and transparency for each data point depending on what each point is assigned in the “Group” column: either an Opaque and Small size point, Semi-transparent and Medium sized, or 100% Transparent and Large size point. Thanks for your ideas!
  df
  #           Group        Class      Height      Weight
  #  1       Opaque small     1 0.831777874 0.859223152
  #  2 Semi-transprnt med     2 0.751019511 0.807521752
  #  3 Semi-transprnt med     1 0.751019511 0.807521752
  #  4    Transprnt large     3 0.527390539 0.599957241
  #  5    Transprnt large     3 0.527390539 0.599957241
    color <- c(rgb(0, 1, 0, 1), rgb(0.5, 0.5, 0), rgb(1, 0, 0))
    plot(x=c(0.0, 0.5, 0.5, 0.0, 0.0), y=c(0.0, 0.0, 0.5, 0.5, 0.0), 
    type='l', col='gray', lwd=2,xlab='Height', ylab='Weight', 
    xlim=c(1,0), ylim=c(1, 0))
    par(new=T)
    plot(x=c(0.0, 0.5, 0.5, 0.0, 0.0), y=c(0.5, 0.5, 1, 1, 0.5), 
    type='l', col='gray', lwd=2, xlab='', ylab='', 
    xlim=c(1, 0.0), ylim=c(1, 0.0), axes=F)
    par(new=T)
    plot(x=c(0.5, 1, 1, 0.5, 0.5), y=c(0.0, 0.0, 0.5, 0.5, 0.0), 
    type='l', col='gray', lwd=2,
    xlab='', ylab='', xlim=c(1, 0.0), ylim=c(1, 0.0), axes=F)
    par(new=T)
    plot(x=c(0.5, 1, 1, 0.5, 0.5), y=c(0.5, 0.5, 1, 1, 0.5), type='l', 
    col='gray', lwd=2, xlab='', ylab='', 
    xlim=c(1, 0.0), ylim=c(1, 0.0), axes=F)
    par(new=T)
    for (i in 1:3) {
    plot(Height[Class==i], Weight[Class==i], xlim=c(0, 1), ylim=c(0, 1), 
    col=color[i], pch=19, xlab='', ylab='', axes=F)
    par(new=T)
    }
    legend(0.8, 0.586,legend=c('Good', 'Fair', 'Poor'), pch=19, 
    col=color, title='Class')
 
    