> I'd like to make a 3d scatter plot of some data I have, essentially a
> graph with xyz axes and a sphere at certain <x,y,z> coordinates. This
> sounds easy enough, but getting the axis labels and tick marks down
> would take some doing. I wonder if any one has written a macro or
> include file that would help automate some of this. I'd also be
> interested if anyone has similar routines for creating 3d histograms.
I don't know of any include files that offer a template like this, although
it seems likely some would be available - if so, Ken Tyler will almost
certainly link to them from http://www.povray.org/links
However, it shouldn't be difficult to create this sort of thing yourself.
One problem might arise if you want grid lines - whether you use cylinders
or textures, the thickness of the lines in the final image will depend on
the resolution you're rendering at. Personally, I prefer to use a checker
pattern for POV-Ray graphs, which eliminates the scaling problem.
For a 3D scatter plot, you could start with three flat boxes as a
background, with the origin at the lower-left-front corner (respective to
the camera). To this you could add unit labels using text objects. To make
the code flexible, use variables to control various aspects of the code:
camera {location <15, 15, -15> look_at <5, 3, 4> angle 45}
light_source {<500, 500, -500> rgb 1.3}
background {rgb 0.5}
#declare GraphSize = <10, 6, 8>;
#declare GridTexture = texture {
pigment {checker rgb 0.3, rgb 0.7}
finish {ambient 0.5 diffuse 0.5}
scale <1, 0.5, 1>}
#declare LabelFreq = <2, 1, 1>;
#declare LabelDecimals = 0;
#declare LabelFont = "Arial"
#declare LabelFontScale = 0.5;
#declare LabelTexture = texture {
pigment {rgb <1, 0, 0>}}
// Graph grid
union {
box {<0, 0, 0>, GraphSize*<1, 0, 1>}
box {<0, 0, 0>, GraphSize*<0, 1, 1>}
box {GraphSize*<0, 0, 1>, GraphSize}
texture {GridTexture}
}
// Graph labels
union {
#declare C = 0; #while (C <= GraphSize.x)
text {ttf LabelFont, str(C, 0, LabelDecimals), 0.1, 0
translate <-0.4, -1, 0.05> rotate x*90
scale LabelFontScale translate x*C}
#declare C = C + LabelFreq.x; #end
#declare C = LabelFreq.y; #while (C <= GraphSize.y)
text {ttf LabelFont, str(C, 0, LabelDecimals), 0.1, 0
translate <-0.4, -1, 0.05> rotate <90, 0, -90>
scale LabelFontScale translate y*C}
#declare C = C + LabelFreq.y; #end
#declare C = LabelFreq.z; #while (C <= GraphSize.z)
text {ttf LabelFont, str(C, 0, LabelDecimals), 0.1, 0
translate <-0.4, -1, 0.05> rotate <90, -90, 0>
scale LabelFontScale translate z*C + x*GraphSize}
#declare C = C + LabelFreq.z; #end
texture {LabelTexture}
}
To add data, you can define a macro that also adds "lines" to the graph
grid:
#macro PlotData (Location, Size, Colour)
sphere {Location, Size pigment {Colour}}
union {
cylinder {Location*<1, 0, 1>, Location, 0.01}
cylinder {Location*<0, 1, 1>, Location, 0.01}
cylinder {Location*<1, 1, 0>+z*GraphSize, Location, 0.01}
pigment {rgb 0 transmit 0.5}
}
#end
PlotData (<3, 4, 2>, 0.1, rgb <1, 1, 0>)
PlotData (<8, 5, 4>, 0.2, rgb <0, 1, 1>)
PlotData (<5, 1, 6>, 0.3, rgb <1, 0, 1>)
All of this is, of course, just the beginning. Thanks to the flexibility of
POV's scripting language and renderer the possibilities are endless... the
hard part is deciding what you want to create!