Re: AxesLabel parallel to 3D axes?
- To: mathgroup at smc.vnet.net
- Subject: [mg111423] Re: AxesLabel parallel to 3D axes?
- From: Fred Klingener <gigabitbucket at BrockEng.com>
- Date: Sun, 1 Aug 2010 04:55:10 -0400 (EDT)
- References: <i2rm0a$r4c$1@smc.vnet.net>
On Jul 29, 6:43 am, David Reiss <dbre... at gmail.com> wrote: > If one sets the AxesLabel option for, for example, Plot3D, is there > any way to set things up so that resulting labels are always parallel > to their own axes? > > ...here is an example, and a customer would like the labels to align > along/paralle the axes rather than what is shown here.... > > Plot3D[x y, {x, 0, 1}, {y, 0, 1}, > AxesLabel -> {"This is the x", "This is the y", "This is the z"}] I've used a couple of approaches to this, a raster and a vector. The vector form is much faster, looks far better, but is a hack, based on undocumented features. I don't think I'd use it on anything critically important. The first resolves the styled text to a Raster, applies raster point properties to a flat 3D grid of square Polygons, then orients and places it in the scene using 3D transformations. Here's a sketch fontSize = 14; imageResolution = 75; (* dpi, say *) imgData = Rasterize[ Style[ "hello,world." , FontFamily -> "Helvetica" , Bold , FontSize -> fontSize] (* give back just the raster data *) , "Data" (* pick an image resolution for the application *) , ImageResolution -> imageResolution (* The combination of the next two option settings produces an array of 2- Lists with the form {gray, alpha} each in the range {0, 255} *) , Background -> None , ColorSpace -> "Grayscale"]; d = Dimensions[imgData] The next line is required to shuffle the rows of the raster and convert the byte values {0, 255} from the Rasterize to the {0., 1.} required for use in GrayLevel[] imgData2 = Reverse[imgData/255.]; This constructs a 2D grid in the x-y plane of square 3D Polygons with FaceForms derived from the Raster. polyGray3D = Table[ Table[ { FaceForm[ GrayLevel[imgData2[[j + 1, i + 1]]] ] , Polygon[{ {i, j, 0.} , {i + 1, j, 0.} , {i + 1, j + 1, 0.} , {i, j + 1, 0.} }] } , {i, 0, d[[2]] - 1}] , {j, 0, d[[1]] - 1}]; Then the Polygon grid can be scaled (maybe using imageResolution) and placed in a scene. I'll apply a Background to make sure that works right. Graphics3D[{ Cuboid[{0, 0, 0}, {1, 1, 1}] , EdgeForm[None] (* Translate a bit in the y direction *) , Translate[ (* and rescale to inches *) Scale[ polyGray3D , 1/imageResolution , {0, 0, 0} ] , {0., -0.25, 0} ] } , Axes -> True , AxesOrigin -> 0 , Background -> Blue , PlotRange -> {{-.2, 1.2}, {-.5, 1.2}, {-0.2, 1.2}} ] ______________________ The second approach exploits the Export/Import mechanism, using the "PDF' mode to generate a vector representation of the letter forms. vectorImg = First@ First@ ImportString[ ExportString[ Style[ "hello,world." , FontFamily -> "Helvetica" , Bold , FontSize -> fontSize , ShowStringCharacters -> False ] , "PDF" , ShowStringCharacters -> False ] , "PDF" ]; Graphics[vectorImg, Axes -> True] vectorImage is composed of 2D Polygons, which represent the letter forms. The scale is evidently somewhere around printer points (1/72 inch). Stripping out everything but the Polygons from vectorImage still leaves a complete rendering of the text. Graphics[polygons2D = Cases[vectorImg, _Polygon, Infinity]] These polygons can be converted to 3D Polygons oriented any way we like, but laying them on the x-y plane is as good as any. Graphics3D[{ Cuboid[{0, 0, 0}, {1, 1, 1}] , EdgeForm[None] , FaceForm[Black] (* Translate a bit in the y direction *) , Translate[ (* and rescale from points to inches *) Scale[ polygons2D /. {x_, y_} :> {x, y, 0.} , 1/72 , {0, 0, 0} ] , {0., -0.25, 0} ] } , Axes -> True , AxesOrigin -> 0 , Background -> Blue , PlotRange -> {{-.2, 1.2}, {-.5, 1.2}, {-0.2, 1.2}} ] Decent built-in 3D text is long overdue in Mathematica. I think. Hth, Fred Klingener