Category: Data Visualization

  • Error Bars in Python: A Practical Matplotlib Guide

    Error Bars in Python: A Practical Matplotlib Guide

    Plot error bars in Python with Matplotlib’s plt.errorbar() function by supplying x and y data plus uncertainty magnitudes through xerr or yerr. The same call supports one uncertainty for every point, per-point symmetric values, and separate lower and upper magnitudes.

    The examples below use one dataset throughout, so you can change the error input without changing the chart data.

    Plot error bars in Python with a complete runnable plt.errorbar() example

    Start with symmetric vertical errors. Each value in yerr specifies the same distance above and below its matching y value.

    Runnable example: import matplotlib.pyplot as plt; x = [1, 2, 3, 4]; y = [10, 13, 12, 15]; yerr = [1, 1.5, 0.8, 1.2]; plt.errorbar(x, y, yerr=yerr, fmt=’o-‘, capsize=4, color=’navy’, label=’Observed mean’); plt.xlabel(‘Sample’); plt.ylabel(‘Value’); plt.legend(); plt.show()

    Here, x, y, and yerr each contain four values, so every point has one matching error magnitude. The fmt=’o-‘ argument draws circular markers connected by a line. The label appears in the legend when plt.legend() is called.

    Choose symmetric and asymmetric values for Python error bars

    Error values describe distances, not endpoint coordinates. For N plotted points, Matplotlib accepts scalar, one-dimensional, or two-row asymmetric inputs.

    • Scalar: yerr=1 applies an error magnitude of 1 to every point.
    • One-dimensional: yerr=[1, 1.5, 0.8, 1.2] gives each point its own symmetric magnitude. The input shape is (N,).
    • Two-row asymmetric: yerr=[[1, 2, 1, 2], [2, 1, 2, 1]] uses shape (2, N). The first row contains lower magnitudes, and the second contains upper magnitudes.

    For asymmetric Python error bars, the lower and upper values must be nonnegative distances from each data point. With the existing dataset, replace the original yerr assignment with the two-row list, then run the same plt.errorbar() call. This creates different uncertainty ranges above and below each marker.

    Add horizontal and combined errors with xerr and yerr

    Use xerr for horizontal uncertainty. It follows the same scalar, one-dimensional, and (2, N) rules as yerr. For example, this call adds per-point horizontal errors while retaining vertical errors:

    plt.errorbar(x, y, xerr=[0.1, 0.2, 0.15, 0.25], yerr=[1, 1.5, 0.8, 1.2], fmt=’o’, capsize=4, label=’Measured values’)

    Both arrays must match the four plotted points. A scalar such as xerr=0.2 applies the same horizontal distance everywhere. To make horizontal errors asymmetric, provide a two-row xerr input, such as [[0.1, 0.2, 0.1, 0.2], [0.2, 0.1, 0.2, 0.1]].

    Style a Matplotlib errorbar chart with fmt, caps, markers, and legends

    The Matplotlib errorbar function separates data styling from error styling, giving you control over readability:

    • fmt: Use ‘o’ for markers without a connecting line, ‘o-‘ for markers and a line, or ‘none’ for errors without a data marker or line.
    • capsize: Set the cap length in points, such as capsize=5. Use capthick to adjust cap thickness when needed.
    • Colors: Set color=’navy’ for the data series and ecolor=’gray’ for the error bars. Add markersize or elinewidth for further control.
    • Labels: Use xlabel() and ylabel() for axes. Pass a distinct label to each errorbar call, then call plt.legend() to identify the series.

    For multiple datasets, repeat the call with different colors, markers, and labels. Keep the error magnitudes aligned with each dataset’s x and y values so the caps and markers remain correctly paired.

  • Use plt.savefig() in Python to Save Matplotlib Figures

    Use plt.savefig() in Python to Save Matplotlib Figures

    Use savefig() in Python to export a Matplotlib figure before displaying it. The basic pattern is to create a figure, draw the data, call plt.savefig(), and then call plt.show(). Saving first avoids blank output caused by display backends that clear or close the current figure.

    The filename controls the usual output format, while options such as dpi, figsize, bbox_inches, and transparent control how the exported file is rendered. This gives you a reliable way to save a figure in Python for reports, web pages, or later editing.

    How do you use plt.savefig() in Python before display with pyplot or Figure?

    Create the figure explicitly and save it before show(). This pyplot example writes a PNG file to the current working directory:

    import matplotlib.pyplot as plt

    fig, ax = plt.subplots(figsize=(6, 4))

    ax.plot([1, 2, 3], [2, 4, 3])

    ax.set_title(“Example figure”)

    plt.savefig(“example.png”, dpi=300, bbox_inches=”tight”)

    plt.show()

    When working with multiple charts, prefer the Figure object. Its savefig() method saves that specific figure instead of whichever plot pyplot currently considers active:

    fig.savefig(“reports/line-chart.svg”, bbox_inches=”tight”)

    Create the destination directory first if it does not exist. The save operation can accept a string path or a path-like object such as pathlib.Path.

    How does savefig() in Python choose extensions, formats, and resolution?

    If you omit format, Matplotlib usually infers the format from the filename extension. For example, chart.png creates a PNG, chart.svg creates an SVG, and chart.pdf creates a PDF. You can also specify the format explicitly:

    fig.savefig(“chart-output”, format=”png”, dpi=300)

    Use PNG for web graphics and other raster images. Use SVG for diagrams that must remain sharp at different display sizes, and PDF for print-oriented documents or vector artwork. Matplotlib may also support formats such as JPEG, TIFF, and PS, depending on the installed backend.

    dpi sets raster resolution, measured in dots per inch. A value such as 150 works for many previews; 300 is a common print setting. DPI increases pixel density for PNG and similar raster formats. It does not control vector detail in SVG or PDF in the same way, because those formats describe lines and text mathematically. DPI can still affect rasterized elements embedded within a vector file.

    How do you save a figure in Python with figsize, transparency, and bbox_inches?

    Set figsize when creating the figure. Its values are width and height in inches, not pixels:

    fig, ax = plt.subplots(figsize=(8, 5))

    At 300 DPI, an 8-by-5-inch PNG is approximately 2,400 by 1,500 pixels before bounding-box adjustments. Change the figure dimensions for the layout you need, then use DPI to control raster density.

    Use transparent=True when the background should show through, such as when placing a chart over a colored document or slide:

    fig.savefig(“overlay.png”, dpi=300, transparent=True)

    Use bbox_inches=”tight” to trim excess whitespace around axes, labels, and titles. It is useful for compact exports, but inspect the result when annotations extend far outside the axes. A tight bounding box can also make the final dimensions differ from the original figsize.

    Why is the saved figure blank or clipped, and where is the file?

    A blank file usually results from saving after plt.show(), saving a different active figure, or creating the plot on one Figure object and exporting another. Save before display, and use fig.savefig() when the figure identity matters. In scripts that do not need an interactive window, save the file and omit show().

    Clipped titles, axis labels, or legends often need bbox_inches=”tight”. You can also reserve layout space when creating the figure:

    fig, ax = plt.subplots(figsize=(7, 4), constrained_layout=True)

    fig.savefig(“final-chart.png”, dpi=300, bbox_inches=”tight”)

    Confirm the output location by printing an absolute path. Relative filenames are resolved from Python’s current working directory, which may differ from your script’s folder:

    from pathlib import Path

    path = Path(“exports/final-chart.png”)

    fig.savefig(path, dpi=300)

    print(path.resolve())

  • How to Create a Bar Graph in R

    How to Create a Bar Graph in R

    To create a bar graph in R, use base R’s barplot() function when you need a quick chart from category values. Use ggplot2 when you need layered styling, grouped bars, or a consistent plotting workflow.

    The key decision is whether your input contains raw observations or values already summarized by category. The same distinction applies to bar graphs in R generally: count raw categories first, but pass precomputed heights directly to the chart.

    How do you prepare counts or summarized values?

    Raw categorical observations contain one category per record. Convert them to counts with table() before plotting. In contrast, a named numeric vector such as sales already contains the bar heights.

    Raw observations:

    observations <- c(“Apples”, “Bananas”, “Apples”, “Oranges”, “Bananas”, “Apples”)

    counts <- table(observations)

    Pre-summarized values for the examples below:

    sales <- c(Apples = 12, Bananas = 8, Oranges = 15)

    Do not treat a histogram as a substitute for a categorical bar chart. Histograms group numeric measurements into intervals, while bar charts compare named categories. If your data is raw, use table(observations); if the heights are already calculated, use the named vector directly.

    How do you create a bar graph in R with barplot()?

    Pass the summarized vector to barplot(). The vector names become the category labels. Use main for the title, xlab and ylab for axis labels, and col for bar colors.

    barplot(sales, main = “Units sold by fruit”, xlab = “Fruit”, ylab = “Units sold”, col = c(“tomato”, “gold”, “darkorange”))

    This produces vertical bars for Apples, Bananas, and Oranges. For raw observations, replace sales with counts. The count values, category names, and their order are then taken from the result of table().

    A matrix creates grouped bars. Each column represents a category, and each row represents a series:

    grouped <- rbind(Online = c(7, 5, 5), Store = c(5, 3, 10)); colnames(grouped) <- names(sales); barplot(grouped, beside = TRUE, legend.text = rownames(grouped), col = c(“steelblue”, “gray70”))

    How do you recreate the chart with ggplot2?

    Convert the named vector to a data frame, then map the category column to the x-axis and the value column to the y-axis. geom_col() is appropriate for pre-summarized heights because it uses the supplied values rather than counting rows.

    library(ggplot2); sales_df <- data.frame(Fruit = names(sales), Units = as.numeric(sales)); ggplot(sales_df, aes(Fruit, Units)) + geom_col(fill = “steelblue”) + labs(title = “Units sold by fruit”, x = “Fruit”, y = “Units sold”)

    For raw observations, use geom_bar(), which counts rows automatically:

    ggplot(data.frame(Fruit = observations), aes(Fruit)) + geom_bar(fill = “steelblue”) + labs(x = “Fruit”, y = “Count”)

    How does an R bar graph handle labels and orientation?

    Set horiz = TRUE in base R to rotate the bars. Use las = 1 to keep the category labels horizontal and readable:

    barplot(sales, horiz = TRUE, las = 1, xlab = “Units sold”, ylab = “Fruit”, col = c(“tomato”, “gold”, “darkorange”))

    In ggplot2, use coord_flip() after defining the chart:

    ggplot(sales_df, aes(Fruit, Units)) + geom_col(fill = “steelblue”) + labs(x = “Fruit”, y = “Units sold”) + coord_flip()

    For grouped values in ggplot2, add a grouping column and map it to fill. Use position = “dodge” for side-by-side bars:

    grouped_df <- data.frame(Fruit = rep(names(sales), 2), Channel = rep(c(“Online”, “Store”), each = 3), Units = c(7, 5, 5, 5, 3, 10)); ggplot(grouped_df, aes(Fruit, Units, fill = Channel)) + geom_col(position = “dodge”)