Customizing Visualizations

Before we go into more details on how to construct complex visualizations, let us explain how one can customize the plots generated by Vizagrams specification.

using Vizagrams
using DataFrames
using Statistics
using Random
using VegaDatasets
df = DataFrame(dataset("cars"));

# We need to drop missing values, as Vizagrams does not handle them yet.
df = dropmissing(df);

When creating a plot in Vizagrams, many defaults are guessed in order to make the specification less verbose. Yet, if one wishes, it is possible to alter such deafults in order to produce custom visuals.

1. Legends

When visualizations become more complex, so do their legends. Consider, for example, the scatter plot with faces as marks.

plt = Plot(
    title="MyPlot",
    data=df,
    encodings=(
        x = (field = :Horsepower,),
        y = (field = :Displacement,),
        color = (field = :Origin, scale_range=:tableau_superfishel_stone),
        smile = (field = :Cylinders, scale_range=(-1,1), legend=(fmark=x->Face(size=7,smile=x),)),
    ),
    graphic = ∑() do row
        T(row[:x],row[:y])U(5)Face(headstyle=S(:fill=>row[:color]),smile=row[:smile])
    end
)


draw(plt, height=400)
50100150200250Horsepower0100200300400500Displacement50100150200250Horsepower0100200300400500DisplacementMyPlotOriginEuropeJapanUSACylinders345678

When a user defines a new encoder, such as smile, by default, no legend will be drawn. If the user wants a legend, it is possible to specify a function, through the fmark argument, which takes the values encoded and draws a mark. Another option is for users to draw the legends as a separate diagram, and incorporate it into the plot.

In the example above, we have used the fmark option. Let us now create a new customized legend.

plt = Plot(
    title="MyPlot",
    data=df,
    encodings=(
        x = (field = :Horsepower,),
        y = (field = :Displacement,),
        color = (field = :Origin, scale_range=:tableau_superfishel_stone),
        smile = (field = :Cylinders, scale_range=(-1,1)),
    ),
    graphic = ∑() do row
        T(row[:x],row[:y])U(5)Face(headstyle=S(:fill=>row[:color]),smile=row[:smile])
    end
)


legend_title = S(:fontWeight => "bold")TextMark(fontfamily="Helvetica",text="Smile",fontsize=8)
legend_marks =
        Face(smile=-1) ↓
        (T(0,-0.4),TextMark(text="Cylinders = 3",fontsize=0.6)) →
        (T(2,0),TextMark(text="...",fontsize=1)) →
        (T(2,0),Face(smile=1) ↓
        (T(0,-0.4),TextMark(text="Cylinders = 3",fontsize=0.6)))
legend = legend_title ↓ (T(0,-10),U(8)legend_marks)

draw(plt + T(plt.config.figsize[1]+30,130)legend, height=400)
50100150200250Horsepower0100200300400500Displacement50100150200250Horsepower0100200300400500DisplacementMyPlotOriginEuropeJapanUSASmileCylinders = 3...Cylinders = 3

2. Frames and Axes

Through the config argument in the graphic specification, users can thoroughly customize the frame and axes of plots.

gdf = combine(groupby(df,[:Year,:Origin]),:Horsepower=>mean,:Miles_per_Gallon=>mean,:Cylinders=>median)

gdf = sort(gdf,:Year)

plt = Plot(
    config=(
            frame_style=S(:stroke=>:white),
            xgrid = (;style=S(:strokeWidth=>30,:strokeOpacity=>0.05)),
            xaxis=(
                    title="years",
                    titleangle=π/2,
                    titlefontsize=8,
                    ticktextangle=π/2,
                    ticktexts=collect(1970:1982),
                    axisarrow=S(:stroke=>:red,:fill=>:red)Arrow(pts=[[0,0],[300,0]],headsize=5),
            ),
            ygrid=NilD(),
            yaxis=(
                    title=TextMark(text="Mean Horsepower",fontsize=7,style= S(:fontWeight=>:bold), angle=π/2),
                    ticktextangle=π/2,
                    tickmark=T(2,0)Square(l=6),
            ),
        ),
    data = gdf,
    encodings=(
        x=(field=:Year,),
        y=(field=:Horsepower_mean,),
        color=(field=:Origin,),
        size = (field = :Cylinders_median,),
    ),
    graphic = S(:opacity=>0.5,:stroke=>:black)Circle()
)

draw(plt,height=400,pad=30)
197019711972197319741975197619771978197919801981years6090120150180Mean Horsepower197019711972197319741975197619771978197919801981years6090120150180Mean HorsepowerOriginEuropeJapanUSACylinders_median45678

3. Titles

At last, we have the title of a plot. The simplest way to customize a title is to omit is from the graphic specification, and instead join it to the plot using the diagram opeartions.

plt = Plot(
    data=df,
    encodings=(
        x = (field = :Horsepower,),
        y = (field = :Displacement,),
        size = (field = :Cylinders,),
    ),
    graphic = S(:fill=>:steelblue,:opacity=>0.2,:stroke=>:black)Circle()
)

maintitle = S(:fontWeight=>:bold)TextMark(text="Main Title", anchor=:e,fontfamily="monospace")
subtitle = S(:fontStyle=>:italic)TextMark(text="Subtitle", anchor=:e, fontsize=8,fontfamily="monospace")

title = maintitle ↓ (T(0,-5),subtitle)

d = plt ↑ title

draw(d, height=400)
50100150200250Horsepower0100200300400500Displacement50100150200250Horsepower0100200300400500DisplacementCylinders345678Main TitleSubtitle