
Brett Champion from Wolfram Research explains how graphics actually work in the Wolfram Language: the difference between axes and frames, how PlotRangePadding adds about 2% by default, why ImageSize and AspectRatio interact, and how coordinate systems like Scaled and Offset let you position things precisely.
Chapters
Sa. Hello, welcome to today's R and D live presentation. I'll be talking about graphics and some of the lower level aspects of graphics and things that I think confuse people sometimes or are not as well understood or as well utilized as they could be. My name is Brett Champion and I'm the manager for the visualization team here at Wolfram Research. And as a result, obviously, I deal with our graphics language in great detail a lot. And even then, there are things that I'm not going to claim to be an expert on. There are things that I learned while writing this talk. So we'll go ahead and get started. This picture at the top is there because that is going to be the fanciest picture in this notebook and it's just here on the title slide. Everything else is going to be very basic visually to counteract some of the intricacies and details of the concepts that we're going to be looking at. So the first thing I we're going to talk about is axes and frames and how they interact and, you know, what the differences are between them. That'll hopefully go fairly quickly. And then we'll talk about plot ranges and padding, image size and aspect ratio. And then we'll get into some of the different coordinate systems available to the graphics language and how they work and some aspects of why you might want to use them or what you can do with them. So the Wolfram language has two independent ways of adding scales to a graphic, and those are axes and frames. And in if you're constructing a graphic entirely by itself, it has neither of these. Those are both turned off by default. By the time you get to a visualization function, whether it's plot or list, plot or bar chart, then one or the other is generally going to be turned on. So axes has a set of options around it. So you have axes, which controls whether the axis line is being drawn at all, whether there's even an axis being done in that direction. Ticks is how you control where the subdivisions on that axis are and how they're labeled and how they're styled. Axis label is going to put labels at the ends of the axes, to the right of the horizontal axis and above the vertical one, and then axis style and tick style that control coloring, fonts, font sizes, that sort of thing. For the appearance of the axes in terms of frame, we have the frame option, which corresponds to axes. We have frame ticks, which corresponds to ticks. In this case, you're going instead of specifying a horizontal specification and a vertical specification, it's going to be a two by two array of values and the two by two are left and right and then bottom and top. And that applies to basically all the frame specifications that in their general form you're specifying left and right and bottom and top. So then we have frame label which is corresponding to axis label and frame style, frame tick style. And then we also have rotate label which determines what whether these labels on the left and right are read left to right or bottom to top. And so I think most people understand those fairly well. Although occasionally there are the cases where somebody will have a graphic say coming out of date list plot that has a frame by default and they try to set ticks or they try to set axis label when they needed instead to set frame ticks or frame label. That being said, it's not always easy to tell which system you're dealing with visually. So here I have two graphics, they look very similar. The plot range in both of the graphics goes from minus one to one in both directions. The one on the left is using axes with an axis origin put down at minus one, minus one. The one on the right is using a frame where we're drawing the left frame but no right frame. We're drawing the bottom frame but no top frame. And as a result they look very similar. And this also comes up because some of the built in plot themes take this approach where we always want an axis at the bottom it so such as plot theme goes to business or plot theme goes to web. And so then those are, you know, this is a frame, this tick over, you know, this axis over here is a frame. Although in this case, you know, the style for this line is being set I think via frame style to be transparent. So you don't see it, but we still show the tick labels and and so it can get a little bit, you know, confusing sometimes of, you know, I set ticks or you know, something and it's not having the effect. I thought if that happens, double check to see, you know, if the plot, if the graphic is actually using frame instead of ticks like you expect. And you can use axes and frames together, but if you do, the axes aren't going to have any ticks, only the frame will have ticks. If you have frames and ticks or frames and axes together. And I mentioned that I'm not all knowing about the graphics language. One of the things I learned while writing this talk is that if you have axes and frames and axes label and frame label, that it will show the axis label and the frame label, I was sort of expecting that the axis label would not be shown similar to how it doesn't show the ticks. So that was something I learned just recently. And you may be thinking, well, okay, what if, you know, I'm doing something where I'm not drawing all the frame edges, then I'm going to get the ticks, right? No. So here we have a frame edge at the bottom. That's the only frame edge. Everything else is being turned off. You know, left is off, right is off, top is off. And so we have one axis and one frame edge. And even in that case we're not going to get any ticks. Let's re evaluate that with true, just to make sure that there's not anything happening with that. None that was there. And so that's, you know, a thing to be aware of. It comes up occasionally where people are trying to construct something and they're wondering, why isn't this showing up? I guess the case that, you know, frequently shows up is somebody is trying to do axes. True. Frame is true and frame ticks is none. So they're trying to just put a frame around the outside and still have the axes with the ticks inside. And in this case you're going to end up with no ticks, maybe do framed instead on the outside of the graphic. It should be possible to get that to work pretty well. But if you've tried this, then, you know, you have discovered that it's not going to work. You know, the axes are not going to have their ticks. So starting off that, we'll now move on to the next portions of the the talk. And I want to define a couple of terms up front with an illustration because as much as I tried to turn this talk into something that was, you know, representable as a tree, there were just, you know, sort of too many circular dependencies where this refers to that and that refers to this. And so we're going to start with getting one definition out of the way first and we'll get into some of the details of this a bit later. But so for a graphic, there's, I mean, lots of different elements of a graphic, but there's two types of two ranges that I want to mention and introduce as a concept. The first is the plot range, and I think I've been reasonably good in this notebook when it gets uploaded to for download, that of distinguishing between lowercase plot range and the Mathematica symbol plot range. And so basically the plot range corresponds to whatever is inside the frame. Of a graphic. I mean, it's actually the other way around. The frame goes around the plot range, but looking at it, it's easier to think of it as if there were a frame, what would be inside it? And that's the plot range. And then the image range is the full extent of the graphic. And so if I select this graphic and I get the orange selection border around it, you can see that my blue image range is going right up to all of those orange boundaries. And generally your content, whether it's coming from a plot or something that you're constructing yourself, is going to show up in the plot range. And the image range is going to have labels generally of some sort, Whether it's tick labels or a plot label, or if you're doing plot with plot label set, and they're sort of pushed off to the right side of the graphic, that's being placed into the image range in one way or the other. So putting that a little bit on the back burner, but having those concepts in mind of what is the plot range, what is the image range? We'll talk about image size and aspect ratio. And so by default, in graphics, the aspect ratio is set to automatic, which basically means that one unit in the X direction has the same visual distance as one unit in the Y direction. Or circles look like circles if you. A lot of the visualization functions tend to set the plot range to 1 over golden ratio or 1. And in those cases, your circles won't necessarily look like circles. And so, I mean, because the aspect ratio is sort of what is the shape of the, you know, what is the height of the plot range to the width of the plot range in terms of points, not in terms of what the coordinates are. And so an important aspect of that is that the aspect ratio applies to the plot range, not the image range. And so here I have a graphic and I'm changing image padding to control how much space we have, you know, how much extra space we have in the image range that isn't inside the plot range. So as P goes up, we get more. So this is the left, right, bottom, top spice type specification again. And so as P goes up, we're going to have more space outside of the plot range to the left and the right. And because I've set the aspect ratio to 1/2, the green plot range in each of these graphics has the same shape. It is the green plot range that is half as tall as it is wide. The overall image range is going, you know, is changing, but the plot range Ratio is not. And so that's an important concept about aspect ratio and image size because a lot of times some people will set an image size to something specific. So you set your image size to 200, 100 and you set your aspect ratio to 1/2 and you end up with extra space. And you end up with the extra space because things like these tick labels are adding, some are eating up part of your image size, but the 1/2 is being applied to this. And so that's sort of tricky to deal with sometimes, especially if you don't know sort of exactly how much space your labels are taking up. And how much space your labels take up may depend on font metrics, which may vary from your computer on one platform to a colleague's computer on another platform. And so that gets kind of tricky. And so now let's talk about image size a little bit. So there are a bunch of built in named image sizes. Tiny, small, medium, large, and then there's automatic. And so with, you know, some settings here that I'm not going to go into a lot of detail about, you know, this is the maximum size of each of those image sizes. So tiny, small, medium, large and automatic. And any graphic you set, you know, using one of these sizes is going to fit as much as possible inside this, you know, inside one of those rectangles. And so I'm going to look at the small setting and I'm going to use some absolute options to extract what the image size is. So here we have a graphic that is image size, small aspect ratio 1/2. And so this is what it looks like. It has width 180. I don't care about the height right now because that's not what limited the size of this graphic. If I do it with aspect ratio 2, then you know, we see the maximal height is 216. And if you do that for all of these, then you can see that if you set image size goes to tiny, it's going to fit inside of a region that's 100 points by a hundred points. Similarly, you know, for these numbers, for, you know, all these other settings. Now you may have noticed something which is that, you know, according to this table, Automatic is the same as medium. It has the same maximal dimensions. But if we go back up to this list, automatic looks like small. It absolutely is way smaller than medium. So what's going on there? And what is going on there is an option called image size multipliers. And so if we have a graphic, and I didn't actually want to bring up the documentation for graphics. And we said image size goes to automatic, which is the default. Then it's this big. And this is a medium size. This is image size goes to medium sized. And so but what happens is if you have that graphic inside of a list or inside of some other type of construct, it automatically gets shrunk down. And so inside of a list, each dimension is cut in half. Inside of another construct, each dimension is cut in a quarter. And so this is so that you can use a graphic inside of a function. And it's not, you know, totally big, that's resizing interestingly. Not sure what's going on there. Anyway, like I said, aspects of the graphics language I'm still learning even after 20 some years. So you can use the image size multipliers option to control that. So here I have that same list, you know, graphics inside of a list, graphics inside of F. And I've set image size multipliers goes to one and one. And then, you know, image, the image. The graphic in both of these cases is its full size, its full normal size. And I've set this option using style on the outside of everything. You could set it by selecting the graphic and going into the option inspector, you know, whatever's easiest. But if you have a need to where you don't want automatically sized images to shrink down inside of other constructs, then you can go change that. And I will frequently do that. You know, if I'm giving a presentation, say, for the Wolfram Tech conference, that I will set it frequently at the notebook level that I want one, one, and I can create a list of graphics, and they're all going to be big, normal size, next to each other instead of being shrunk down. So coming back to image size specifications, you can control what the width of a graphic is. So image size goes to 100. Both of these graphics are 100 points wide, regardless of their aspect ratio. And this is really 100 automatic, which means that the width is 100. The height is computed accordingly according to the aspect ratio. And there's no padding around this. So when I select these graphics, my orange border is tight to those orange rectangles. Similarly, I can do the same thing with height. So I can say automatic comma 100. And then all of these graphics will have the same height. The region is tight to the content. I mean, and that's useful. A lot of times if you say 100, 100, then the graphic is going to be 100 points by 100 points. And if your aspect ratio doesn't match up with that really well. Then you end up with these graphics where the selection is not tight to your content. And so you have all this extra space at the top and the bottom, which I'm using background, the background option to sort of emphasize what that region is. And you can see where the orange border is. All that space in this one, it's on the left and the right. If you want to be tight and fit within a 100 by 100 region, which is, you know, in this case equivalent to what tiny is. But suppose you wanted 120 by 120 so it's not tiny but a little bit bigger. Then you can use up to 100 and up to 100 for the width and the height. And then if your graphic is wide, it's going to be 100 pixels or 100 points wide. If it's tall, it's going to be 100 points wide. But without having excess padding around it. If you really have, you have a shape that you really want to fill and you don't want the padding, you can also, you can say I want 200 by 100. And then set aspect ratio goes to full and it will adjust the the aspect ratio for the plot range so that everything fits inside a region that is 200 points by 100 points. Obviously in this case, then your circles will no longer look like circles. But if you're just doing a plot and you don't have things where you care about circles looking like circles or 45 degree angles looking like 45 degree angles, then this may be a useful approach for you. And this is not too far off from, you know, in this particular case, it's not too far off from the one over golden ratio that plot would use by default. So now let's circle back around to that plot range and image range and talk about plot range. So where do the plot range and the image range come from? So the plot range is determined by two options, plot range and plot range padding. And I'm going to change some of my formatting a little bit. And by default plot ranges all in a normal graphic. In plots and charts it's usually set to automatic. And those do special things to determine what to show, what's important, what's not quite so important. And with plot range that goes to all that basically means that all the finite primitives are going to be shown pretty much in their entirety, you know, finite primitives. So if you include infinite line, it's going to get cut off somewhere. Okay. And where is an aspect I don't fully understand, especially when the scene only contains infinite primitives. And then, as I was saying, the other option is plot range padding, which is automatic, which means that there will be 2% padding on each side. And so here I have a graphic. I have an orange rectangle that goes from 00 up to 200, 150. And I have the frame turned on. And the fact that this rectangle doesn't go all the way to the frame edges is because of plot range padding. In this case, I have one rectangle. The limits of that rectangle are determining what the plot range is. Pretty exactly. So if we look at absolute options of graphic and we look at plot range and plot range padding, you see that the plot range is basically 0 to 200 and 0 to 150. So it is tight to that orange rectangle. And then we have a little bit of padding about 4 points on each side. Sorry, not 4 points of 4 units on each side. And so, and the 2% is that this padding, so this 4.16 distance here is 2% of the total plot range. So from frame edge to frame edge, this space is 2%. This space is 2%. This space is close to 2%. You know, automatic does a little bit of adjustment to balance out the padding in ways that I understood at one point and have forgotten. So, but it's approximately 2%. It's a little bit over in this particular case. If you with the default setting of plot range padding automatic, it won't add padding to explicit plot ranges. So in this case, I'm, you know, have that same graphic and I'm saying The plot ranges 0 to 200 and 0 to 150. And now the frame is tight to that and the plot range padding is zero. If I give an explicit padding, then that is done in addition to an explicit plot range. So if I say I want 10% on every side or if I want 20 units on every side, those are respected and let's make those both a little bit bigger. And so. Understanding the interaction between plot range and plot range padding is useful and sort of where you're going to get some extra space and potentially needing to account for it. Or sometimes it's, why am I not getting space? I want a little bit of space between my frame and my content. And in that case, it's probably because something, whether it was you explicitly or something that you're building on top of, introduced a specific plot range. And then automatic plot range padding clamped down tight around it. And so the other thing that I wanted to show here is that, you know, with, you know, sort of, whether it's with scaled or, you know, the user coordinate, so to speak, those both scale with the image size. And so as the image gets bigger or smaller, this padding stays at whatever percentage and becomes visually larger or smaller correspondingly. So now let's look at the image range and in particular, image padding. And so by default, image padding is automatic and it's going to automatically leave space for things that it needs to, for things that it thinks it needs space to render for the graphic. And so, for example, we have our frame and we have our frame ticks on the outside. And in this case, those are pretty much what's accounting for all of the image padding. All of the difference between the plot range and the image range, we can turn image padding off, in which case these, you know, it all gets set to zero. There's no space left for anything outside of that. And our green region becomes the same as the blue region. We don't see our frame labels or frame tick labels, any of that stuff. We can also set image padding to a, you know, a specific value. In this case, this is in points. This is in the same system as how you specify image size. And, you know, in this case, I'm setting 30 on every side, which is enough to include all of these frame tick labels. You could do a left, right, bottom, top type specification and, you know, trim off the stuff on the top and the right where you think it's not as necessary. And so, but the difference between the green plot range and the blue image range is controlled by the image padding option. And in contrast to plot range padding, because this is an absolute coordinate system in absolute units that corresponds to image size. As I change the image size, this is 30 points no matter what size it is. So the visual width of the blue border around the green rectangle is the same across all three of these graphics. One other thing to be aware of for the plot range versus the image range is that so by default, if you have a graphic and you're sort of drawing in the graphic and you have your frame and you've got some space outside the frame, that image padded region, the blue region is fair game for content to draw into. And so here I have a circle, and it goes outside of my plot range that I've set specifically. And you can see that the circle goes past the frame edge and only stops when it hits the edge of the image, the overall image edge. There is an option for this, which is plot range clipping goes to true, at which point this circle primitive will only draw up to the edge of the plot range. And so if you don't want things to cross your frame edges when you zoom in or whatever, then this is probably what you're going to want to set. It is true by default for most plots and charts, although there are some cases where it's true by default. But in order to do an effect with labeling, it sometimes has to be disabled and set packed to false. See. That text is from an early iteration. I forgot to rewrite it. But just alluding, you know, re emphasizing that this padding, you know, the image padding is automatic by default. It's going to determine what it needs and use that. Usually it's going to come from a frame or an axis or something else that is specifically attempting to draw outside of the plot range. In this case, I'm using axes instead of frame. And you can see that the plot range is still this green rectangle. And we have in this case the difference between the padding between the image range and the plot range is coming from the tick labels instead of the frame ticks. And even though there's like no frame over here, this 200 is pushing it out. If you don't have a frame or axes, then usually these will be the same. And so you won't necessarily. I mean, in that case the plot range becomes the image range. And so now let's talk about some coordinate systems. So there's multiple coordinate systems that you can use to construct graphics. And this gets into some detail, not all detail. The most common one is sort of your typical user coordinates. You know, your Cartesian XY specified in the same units as whatever your plot range is. So this is the I want to circle at 55 with radius 10 type thing. You can have a scaled position where you give an X position and a Y position. And X and Y are scaled are values in a scaled coordinate system that run from 00 at the bottom left corner of the plot range of the green rectangle to 1:1 in the top corner, top right corner. Image scaled is the same except it goes from it's over the image range. So the blue rectangle is what it's mapping 012. And so we'll look at a graphic. So we have a graphic, we have a rectangle which is light blue. And this is going from image scaled 00 at the bottom left to image scaled 11 at the top right, we have a frame just to make sure that there's a difference between our plot range and our image range. We have a rectangle that's going from the light green, that's going from scaled 00 to scaled 1. 1. We have a blue point which is at scaled or image scaled 0.5, 0.5. So this point is halfway between the left edge and the right edge of the image range of the overall graphic. Similarly, we have a point that is green at scaled 0, 5.5. And so this point is halfway between our minimum X range and our maximum X range. And you know, similarly for Y. And then we've got a good old fashioned point at 50 50. And you know, just for fun, this graphic has a light gray background and you can't tell because you can't see the light gray background because this rectangle that goes from image scaled 00 to image scaled 1. One is completely and perfectly covering it up. So. What are the advantages of using scaled coordinate systems or image scaled coordinate systems? They don't depend on the plot range. So I can take that graphic, I change the plot range from 100 to 200, and those points are in exactly the same place. The black point has moved it, you know, it's still it, it's moved visually, it's still at 50, 50, but now there's 150 units to the right of it instead of 50 units to the right of it. And these coordinate systems apply whether or not I have axes or frame or neither. And so in this case, we're turning off the frame, we're turning on the axes. That adjusts our image padding a little bit. So we've got a little bit less padding on the left on pretty much every side. Top maybe top and right maybe stayed about the same. And so as a result of the plot range and the image range being closer together and especially in this case being more symmetric, those blue and green points are moving closer together. And if we get into a situation where we have where the plot range and the image range are the same, then those that blue and green point are exactly overlapping. We'll go back to. Right. So those are exactly overlapping. And so scaled and image scaled also have two argument forms. And this is where things start to get really fun. And then, and so then these are, I want to move a fraction of my plot range or a fraction of my image range away from some other position. And then we also in this point get offset, which does the same thing. But dx and DY are in points. And so here we have a similar graphic to what we were looking at before. We have the same light blue and green rectangles. We have the same black point at 50 50, but now our blue point is image scaled point one up and to the right from our Black Point at 50 50, our Green Point is down and to the left by 10% of the plot range from that black point. And we now have a red point that is offset 20 points to the left and up from 50 50. And so if you were to measure this distance from green to black, that would be 10% of that. And this distance for blue is a little bit larger because it's 10% of that distance. And this is just 20 points absolute scale to the left and up of the, of the black point. And so now when we change the image size, you see that the blue and the green points shrink with the image size. So it's always 10% distance from green to black as a fraction of the width of the graphic. Same for the blue, but with, sorry, width of the plot range for green, width of the graphic for blue. But offset is in points and it's always 20 points to the, you know, northwest of the black point. And so this distance from black to red is visually the same in all of them. You know, and if I take this and I move it, you know, I resize, everything is moving relative to the black point except the red one. And that's kind of cool. And then the craziness starts, which is that you can combine these. And so suppose you want a point that's halfway across the plot range and 50 points up. So you could do this. So we're going to create a sort of an orange point. It is going to be offset zero to zero, no horizontal offset. We're going to shift it up 50 points. And. But what is our point that we're going to refer to? We're going to refer to a scaled point and our scaled point is going to be 50% of the plot range to the right and 0% up from 00. And I'm going to set my plot range at 0 to 200, 0 to 150. So we can see that we are 50% over and 50 points up. And as I change the image size, the distance from the bottom to the point is always the same. It's always 50 points. And as we, you know, as this image is changing size, this is moving, it's always centered inside of our plot range. So if we take this, let's Move that up a little bit, you can sort of see where this distance doesn't change, but that the horizontal position remains centered. So if I make this small enough, then that point's all the way at the top, etc. If I change the plot range, if I start changing the plot range so from 0 to K to 0 to K in both directions, then the vertical distance stays the same. And even though the plot range is changing, it's going from 0 to 100, 0 to 150, 0 to 200. This point is always remaining centered with regard to that. And so this can be useful things to know, especially with I want, I know where I want something and I want something close to it, but not right on it. And so, for example, a lot of the labeling and callouts that we use in the visualization functions are making use of these types of coordinate systems to put a label close to a point, but not right at the point. And so that was the last thing I wanted to cover for today's talk. And now we'll look at what questions we may have. And let's see, George Woodrow asks, is the notebook available anywhere? Not yet, but it will be very soon after this talk and it will be posted on the community post that goes along with the RD live stream from Chase. For multiaxis, when will X men X max Y min Y max for plot range be honored rather than defaulting to plot range goes to all. And so I think that is referring to multiaxis means multiple things and they're all interesting. That was not what I wanted to do. I wanted to. So multiaxis I think in this case means let's do. And that option name is escaping me at the moment, multi axis arrangement. And so let's magnify that. So setting plot range to plot to min max range on this. I mean, I don't think that X min X max, Y min Y max really can work exactly on this. It would have to be something that would span to multiple specifications of controlling this axis and this axis and that axis and all four of the axes that are here. And so when you get to the multi axis things, simple plot ranges stop making as much sense and things end up being more constructed. And in those situations it tends to use PlotRangeal because there's no unique coordinate system. And so you go to a constructed coordinate system that's useful for assembling things, but then it's not quite so much easily modified by users. And I mean, interestingly, and I'm not going to get into it in a lot of detail right now, but in cases like this where we're drawing multiple axes, you know, and so this. Okay, so earlier on I said that, you know, there were two independent things that, you know, controlled scales, axes and frame, that was a lie. There's a third, which is Axis object, which is experimental and worthy of a talk all on its own. And so even though this looks like a framed graphic, it is actually constructed using multiple axis objects. And if we were to take this and I'm going to go off script and play with fire. And so let's do prologue and we'll use my favorite things. So we'll do. Light blue rectangle of scaled of 0. 011, make a copy of that. We'll look at light green. Image scale to scaled. So what you'll see here is interestingly that that green scaled region is not as tight to where we managed to draw the axes as I was expecting. But interestingly that this axis on the left is being drawn entirely in the image padding. And usually it's difficult for primitives to draw outside of the plot range. Even in the circle case where it was going through the frame edge, the defining characteristics of that circle lived inside the plot range. So the center point for that circle was inside and then it happened to draw through. In this case, it's drawing entirely outside, but not really. So what's happening in this case is this axis is placed in some sense inside the plot range, but the positioning for it involves those offset coordinates. And so we are offsetting a certain number of points to the left from points that do live inside that plot range. And so that's where, you know, sort of the power of a lot of these comes from, is starting with something and having the flexibility to start from here, but position it off to the side a certain amount. And on top of that, Access object is special in its own ways in that normally a primitive that was drawing out here wouldn't be able to contribute to the image padding, the automatic image padding. But axis object is able to, specifically, because when we were designing it, we knew that we wanted to do things like this, that we would have to draw axes in image range territory. So let's see. Are there any other questions? And I'm not seeing any. And we've been going for about 55 minutes. So with that, I will thank you for attending this talk and encourage you to attend future R and D live presentations. If you have topics you'd like to see us discuss, let us know. I have some topics I'd like to discuss next year. That didn't quite fit into this today's talk. I had them tentatively planned and was getting to it. I was like, that's gotta be a talk all on its own. So things like access object, things like intricacies of insect, I think would both be really interesting talk. Talks about things that are powerful and not always as well understood. So thank you for attending and hope to see you next year sometime. Thank. You.
More from Guy

Cheryl Strauss Einhorn | The Human Edge: Smarter Decisions in the Age of AI | Talks at Google

Rachel Glennerster | Innovation and the Center for Global Development | Talks at Google

Rebecca Winthrop | Rethinking the Purpose of Education in the Age of AI | Talks at Google

Dr. Robert Wachter | A Giant Leap: How AI Is Transforming Healthcare... | Talks at Google






