Grid, Axes, and Labels
In the world of data visualization, it’s crucial to have the flexibility to present a grid in a plot. The Plotters library empowers us to achieve this by enabling the mesh feature. By simply incorporating the statement chart.configure_mesh().draw()?;
into our code, we can enhance the visual appeal and clarity of our plots.
evcxr_figure((640, 240), |root| {
let mut chart = ChartBuilder::on(&root)
.build_cartesian_2d(0f32..1f32, 0f32..1f32)?;chart.configure_mesh().draw()?;
Ok(())
}).style("width:100%")
The line ChartBuilder::on(&root).build_cartesian_2d(0f32..1f32, 0f32..1f32)?;
allows us to manually set the limits of the x-axis from 0 to 1 and the y-axis from 0 to 1. By specifying these ranges, we have precise control over the displayed region of our plot, ensuring that the most relevant data points are emphasized.
To enhance the clarity and understanding of our plots, it is essential to provide proper labels for the axes and a descriptive title. Let’s consider the following code snippet as an example:
evcxr_figure((640, 480), |root| {
let mut chart = ChartBuilder::on(&root)
.caption("Plot Demo", ("Arial", 20).into_font())
.x_label_area_size(50)
.y_label_area_size(50)
.build_cartesian_2d(0f32..1f32, 0f32..1f32)?;chart.configure_mesh()
.x_desc("x = Array::range(1., 7., 0.1);")
.y_desc("y = f(x)")
.draw()?;
Ok(())
}).style("width: 60%")
In this code, we have added the chart.configure_mesh().x_desc(“x = Array::range(1., 7., 1.);”).y_desc(“y = f(x)”).draw()?;
statement to enrich our plot with meaningful annotations. By including x_desc(“x = Array::range(1., 7., 1.);”)
, we label the x-axis with a concise description of the data being plotted. Similarly, y_desc(“y = f(x)”)
assigns a label to the y-axis, indicating the functional relationship. Furthermore, Caption(“Plot Demo”, (“Arial”, 20).into_font())
provides an informative title to give context to the plot. These elements collectively improve the interpretability of the visualization, ensuring that viewers can easily comprehend the purpose and content of the plots.
In addition to labels and titles, Plotters allows us to create a legend to distinguish between multiple curves within a plot. By passing an argument for the label parameter in the label
function and subsequently calling the legend
function, we can generate a legend. Consider the following code example:
evcxr_figure((640, 480), |root| {
let mut chart = ChartBuilder::on(&root)
.caption("Plot Demo", ("Arial", 20).into_font())
.x_label_area_size(50)
.y_label_area_size(50)
.build_cartesian_2d(1f32..7f32, 1f32..14f32)?;let x = Array::range(1., 7., 0.1);
chart.configure_mesh()
.x_desc("x = Array::range(1., 7., 1.);")
.y_desc("y = f(x)")
.draw()?;
chart.draw_series(LineSeries::new(
x.iter().map(|x| (*x, *x)),
&RED
)).unwrap()
.label("y = x")
.legend(|(x,y)| PathElement::new(vec![(x,y), (x + 20,y)], &RED));
chart.draw_series(LineSeries::new(
x.iter().map(|x| (*x, *x * 2.0)),
&GREEN
)).unwrap()
.label("y = 2 * x")
.legend(|(x,y)| PathElement::new(vec![(x,y), (x + 20,y)], &GREEN));
chart.configure_series_labels()
.background_style(&WHITE)
.border_style(&BLACK)
.draw()?;
Ok(())
}).style("width: 60%")
By executing this code, we create a legend that corresponds to the various curves in our plot. The legend()
function automatically generates a legend based on the labels provided after calling the draw_series()
function. It helps viewers identify and differentiate between the different functions being plotted. In conjunction with the grid, axis labels, and title, the legend enhances the overall readability and comprehension of the plot.
By default, the legend box is positioned at the middle right of the plot. However, if we prefer to change the location of the legend box, we can do so by specifying a SeriesLabelPosition
position parameter within the position
function. Let’s modify our code snippet accordingly:
evcxr_figure((640, 480), |root| {
let mut chart = ChartBuilder::on(&root)
.caption("Plot Demo", ("Arial", 20).into_font())
.x_label_area_size(50)
.y_label_area_size(50)
.build_cartesian_2d(1f32..7f32, 1f32..14f32)?;let x = Array::range(1., 7., 0.1);
chart.configure_mesh()
.x_desc("x = Array::range(1., 7., 0.1);")
.y_desc("y = f(x)")
.draw()?;
chart.draw_series(LineSeries::new(
x.iter().map(|x| (*x, *x)),
&RED
)).unwrap()
.label("y = x")
.legend(|(x,y)| PathElement::new(vec![(x,y), (x + 20,y)], &RED));
chart.draw_series(LineSeries::new(
x.iter().map(|x| (*x, *x * 2.0)),
&GREEN
)).unwrap()
.label("y = 2 * x")
.legend(|(x,y)| PathElement::new(vec![(x,y), (x + 20,y)], &GREEN));
chart.configure_series_labels()
.position(SeriesLabelPosition::UpperMiddle)
.background_style(&WHITE)
.border_style(&BLACK)
.draw()?;
Ok(())
}).style("width: 60%")
By including the parameter position(SeriesLabelPosition::UpperMiddle)
on the configure_series_labels
function, we reposition the legend box to the upper middle of the plot. This allows us to fine-tune the placement of the legend, ensuring it does not interfere with the plotted curves or other annotations. The ability to customize the legend location adds to the versatility and aesthetics of our plot.
By understanding and utilizing these features in Plotters, we can create visually appealing and informative plots, customize axis limits, add labels and titles, incorporate legends, and save our visualizations as image files. These capabilities empower us to effectively communicate and present our data in a compelling and meaningful way.