 One of the things I love about programming in R is that there's a phenomenal community of R programmers out there ready and willing to help you if you ask a question. And so there are a variety of discussion forums out there where you can get help. So Stack Overflow is definitely a viable candidate. Another great candidate is the community forum that is hosted by RStudio. Now Stack Overflow tends to have a bit of a reputation for not being super nurturing, there's a lot of programmers and dudes that just want to tell you how smart they are. There are certainly some very smart and very, very helpful people over there but it tends to be a little bit of a caustic environment. I found that the discussion forum hosted by RStudio is actually fairly nurturing and does a really good job of helping people at all levels of programming ability. So we can ask questions on these discussion forums but the challenge becomes who's going to answer these questions? Well in today's episode I'm going to show you what makes for a good question on one of these discussion forums and then how I go about answering questions that people have. Over here at community.rstudio.com you can see the discussion forum that they are hosting that's basically laid out where people will ask questions and they title their questions. Perhaps they tag it, you know here you've got some for machine learning and modeling, Shiny General, RStudio, whatnot and then you've got an indication of how many people are involved in this ongoing discussion, how long it's been up there, how long it has been since the person asked the question. And so one of the questions that caught my eye was this post on Black Border around certain points in GG Plot and so what caught my eye was that this had the question with the name GG Plot in it and so that initially queued me that hey Pat you know something about GG Plot maybe that is something that you could answer and when I saw Black Border around certain points that also piqued my interest because I know there are certain plotting symbols where you can actually change the border of the symbol to be a different color than the inside of the plotting symbol and so this is the question that I want to take on and show you what I think of the question kind of my critique of their question and then I'm going to go about showing you how I would solve this problem. We talked about the title, it's descriptive, it gets my attention, it put in a keyword there that you know it's something that triggered an idea for me that I realized I could answer this so it drew me in right. So C right 1, I don't know who they are but their question is I'm plotting some data using GG Plot 2, the data has several different colors and a few different shapes right so one variable is being mapped to the color aesthetic and one variable is being mapped to the shape aesthetic. They want to put a black border only around the circles and triangles but they want to leave the squares to not have a border. So basically what they say is that we need something like scale border manual if there's anything that existed like that to be able to control what shapes get a border and which ones don't. So we will not be able to find scale border manual but we'll work up a trick that will allow us to get the result that I think they're after. One of the great things about this post is that they put in a minimal reproducible example, a minimal reprex and so there's two lines of code here can't get too much more minimal than that and then they show the output. What would be really nice that they didn't do would be to show what they want it to look like right so they could take this PNG image and they could then perhaps go into PowerPoint or something and kind of draw onto it what they want those square symbols to look like versus the circles and the triangles but I think I know what they're after here. So on the whole I think this is a pretty good question and I'm going to go over to our studio I'm going to copy this code and we're going to make sure we can reproduce it and then I'm going to show you how we can achieve the result that I think they're after. Here in our studio I'll open up a new R script and I'll paste in that code that they posted onto the discussion forum I'll do library tidyverse make sure that loads and then I'll go ahead and run their code to make sure that I get the result that they had in their discussion post and this plot looks identical to what they had and so we're in good shape to go. I'm going to go ahead and clean up their aesthetics a little bit so it doesn't go off the right side of my screen. One thing I want to point out about this minimal reproducible example is that they're using a data set called MT cars. MT cars comes pre-baked into R and it is a data frame I think it's from Car and Driver magazine from back in the 70s looking at different types of cars their miles per gallon number of cylinders all sorts of different statistics that gear heads would get really excited about with different cars. We don't need to care about the cars what we care about is that there's a variety of different types of variables in here continuous categorical all sorts of different things that we can use to again create minimal reproducible examples and so MT cars and other things like it are really nice because if I'm going to post my code then I need to post data with it right and so the idea then is that if I use MT cars I don't have to share my real data. One of the things I'll also comment on with reproducible examples is that it's very common that I might have a hundred lines of code and I'm trying to solve a problem right well I'm not going to post all hundred lines of code I'm only going to post what's really relevant and as we said that also goes for the data well if I've got that hundred lines of code and I start chipping away at really isolating where is the problem or where is it that I'm struggling with invariably I get to a few lines of code and more often than not actually solve my problem right by trying to minimize things and simplify things I can figure out where the problem is and solve it more directly and if I can't solve it well then I have this minimal reproducible example and in this case it created the figure that we just looked at but in other times it will create an error message and so then the first step that somebody wanting to help me will do as I've already shown you is run this code to generate the figure or to generate the error message that I'm seeing as I also said it's often also helpful to point out to the people reading your thread what you wanted to say what do you want it to look like what you want the output to appear like so we've got this minimal reproducible example and something I want to call your attention to is that our studio actually publishes a number of cheat sheets and so if you go to help cheat sheets you can see a variety of different cheat sheets here they've got others that aren't in this menu but I like the one that's data visualization with ggplot2 and actually I don't just like this one I like all of them and back on campus I have a stack of cheat sheets that I've printed off that I regularly thumb through to try to find the syntax that I'm after you know there's clearly just so many different functions and so many different options and these cheat sheets are really helpful for kind of triggering my memory of what I'm trying to do and to get that syntax just right so one thing that I want to call your attention to on this ggplot2 cheat sheet is in the bottom left corner of the first page there's a little legend here showing you what plotting symbols correspond to what shape number and if you look at symbols 21 through 25 here you'll notice they appear a bit different than all the others they are light blue on the inside and they have a darker blue border these symbols 21 through 25 allow you to use the fill aesthetic to change the interior color and the color aesthetic to change the exterior the border of the plotting symbol and so we are going to use shapes 21 and 24 those are the bordered circle and triangle and we'll also use 22 which is the square and so by using these symbols we can change again the interior color with the fill and the border color using the color aesthetic so returning to our code we can do scale shape manual breaks and we'll do three four and five for the number of gears and then values we'll do 21 24 and 22 again that gives us the circle the triangle and the square you'll notice though that these are not filled symbols right that we can kind of see through them we can see the grid line that these are sitting on and so we have mapped the carburetor variable whatever that means to the color I'd really rather that be the fill right so I can say fill as character carb now I see the interior of the shape is one color and the border is black I'd like to make these points a little bit bigger so it's easier for you to see so I'm going to go ahead and do geom point size equals three obviously our points are a bit bigger now they're easier for us to see and there's a couple things that we still have some work to do so the first is as the original poster commented they wanted the squares to not have a border well these have a border a unique aesthetic that goes with symbols 21 through 25 is an aesthetic called the stroke so you could do stroke equals two this then gives us a thick border on our symbols right and so we could do 0.2 and get a more thin line right we could do 0.5 to get back to the default what I'd like to do is to have a scale stroke manual unfortunately there are no scale stroke anything functions that allow us to manipulate the stroke the thickness of our border so I'm going to go ahead and remove that aesthetic for now and the trick that I'm going to do instead of that stroke that scale stroke whatever that doesn't exist is I'm going to map the number of gears to the color so this is going to take a couple steps but bear with me again we'll do color equals as dot character gear and so now we see we've got different border colors for each of the three different plotting symbols right and so what we can then do scale color manual breaks and we'll do three four and five again and then our values I'm going to do black black and let's do red so it sticks out and so now we see that the three and four gear cars have black borders whereas the five gear cars have their squares but they have a red border now I don't want red right the original poster didn't want any color there so instead of red I'm going to use a function called RGB and so RGB allows you to give the function a red a green a blue value between zero and 255 to get whatever color you want you can also give it an alpha which is the level of transparency so I'm going to do 000 which I think is black and then I'll do alpha equals zero and what that should do is that should give it a black border on those squares but the alpha is going to be zero which means that there will be no border and so now what we can see is that we do have these squares but they don't have a border around them right that's pretty slick okay one thing that I noticed though is that by removing the border those symbols get a little bit smaller so what I'd like to do is let's use scale size manual to make the squares a bit bigger so again we'll do scale size manual and we'll do breaks of three four and five and then I'll do size equals three I need to put that in the c function so three three and four and I'm going to remove size from gion point and I'm also going to then take that shape as character gear and also make that then size and I have size here and I didn't mean size I meant values so now we see that our squares are a bit bigger than they were they're more on the same size as our circles and our triangles and of course they don't have a border I think we've accomplished what the original poster wanted however if you look at the legend there's a few problems here which will allow us to look at some other features of these scale manual functions that will allow us to manipulate the way these legends appear so specifically if you look at this as character gear legend you'll notice that the five is missing and that's because again the border is transparent right there's nothing there so what I'd rather do is override these colors and these fills that I have for the different shapes and make them black right the other thing I'd like to do then is that if you look at my colors for my as character carb they are all black right and so it's using the color aesthetic to set the color of these different colors so I need to override these two legends to make them appear the way I want them to to override the way those legends appear I can come into each of the scale whatever manual and I can then do guide guide legend and we are now going to override AES so that's the argument and we'll then say list we'll give it a list of values of arguments and their values so I could say fill equals black and color equals black so now we have the legend for the shapes looking pretty good the next thing I want to turn my attention to are the colors of the plotting symbols in this secondary legend and again they've all been turned to black to change the color I'm going to add another scale so we'll do scale fill manual we'll do breaks equals one two three four six and eight those were the six different carburetor values I have no idea what those mean and then for our values I'm going to use the rainbow function we now see that our shapes in the plotting window have changed to different colors but again as we've seen our fill colors or the colors in our legend are still all black so again we can override the guide by doing guide guide legend and then do override dot AES and we'll do list color equals rainbow six we now have those six different colors that correspond to the colors in the plot now when I have done this in my work where again I have one variable getting mapped to the shape another variable mapped to the color it always makes me a little bit worried that my audience will be confused that I have a circle for three and then I have circles down here for my plotting shape in my color legend I'd prefer to have a different shape for my color legend so we can do that again down here in this override AES let's do shape equals 18 and that gives us diamonds and so again it's a shape that isn't being represented in our shape legend those are really small though so why don't we go ahead and make those bigger and again we can do this in that same list function for the override AES we'll do size equals five and now we have basically a swatch for each of those six different colors that is a shape that doesn't overlap with the shapes that we're using for the three different gear levels again what was most important to the original poster on that discussion thread was that the squares not have a border around them there's probably a variety of other ways that you could do this this is how I did it again my strategy was to use those plotting symbols between 21 and 25 where you can set the fill color as well as the border color then for those symbols where I didn't want a border color I made them transparent using the RGB function setting that alpha value to zero along the way we saw how we can use override AES within the guide legend function being passed to the guide argument for each of those scale manual functions to change the different ways that these legends appeared I think you could generalize this to a lot of different applications I know I have used this in some of my projects as I mentioned earlier where I've got different things being mapped to the shape as well as the color again I hope you found this useful in thinking about how we can of course make this type of plot but more importantly thinking about going into these discussion forums and not just reading them for answers to help you with your coding but really think about and take to heart the opportunity we have to teach others and to help other people overcome their problems it's a fun challenge and I find that I really learn a lot by trying to really dig in to solving the poster's questions sometimes you know the poster might say well that's not exactly what I wanted right and so you can have some give and take and some discussion what I'm going to do is I'm going to go ahead and save this image and I will write a response that I will put a link to in the description down below of this video and maybe I will put a link in the thread to this video so the the poster can see a bit more of the discussion and my thought process that I went through as I went about creating this code so again I encourage you to dig into these different discussion forums always try to be supportive and helpful to the the posters don't be a jerk but no one likes that and and and really this is a great way to improve your r skills to take someone else's problem and to try to solve it again go out there and try to find a problem and make our r community a better place for everybody