Guarding Against Misleading Data

[This article was first published on Numbers around us - Medium, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

The IBCS ‘Check’ Principle

In the complex world of business intelligence (BI), the ability to present data accurately and transparently is critical. Whether crafting a dashboard for executive decision-making or generating a report for operational analysis, the clarity and honesty of data visualization can make or break the effectiveness of the message. This is where the International Business Communication Standards (IBCS) come into play, offering a robust framework to ensure that data is communicated in a way that is both truthful and impactful.

One of the cornerstones of the IBCS framework is the acronym SUCCESS, which outlines a series of principles designed to improve the clarity, consistency, and effectiveness of business communication. Today, we focus on the “Check” principle, the second “C” in SUCCESS, which emphasizes the importance of guarding against misleading data.

The “Check” principle is all about ensuring the integrity of your visualizations. It’s not just about avoiding outright lies or fabrications — it’s about being vigilant against more subtle forms of misinformation that can creep into data presentation. These include manipulated axes, distorted visual elements, inconsistent scales, and unadjusted data that can lead to misinterpretation. The goal is to create visualizations that are honest, clear, and easy to understand, allowing decision-makers to trust the insights they derive from them.

In this episode, we will delve into the specifics of the “Check” principle as outlined by IBCS, exploring how to avoid common pitfalls in data visualization. We’ll discuss best practices for ensuring accurate and honest representation of data, supported by practical examples in R — a powerful tool for data analysis and visualization. Through these examples, we will see how R can be used not only to create effective visualizations but also to ensure that those visualizations adhere to the highest standards of accuracy and transparency.

Avoiding Manipulated Axes

One of the most common ways that data visualizations can mislead is through the manipulation of axes. The scale and type of axis chosen for a chart can significantly influence how the data is perceived, potentially distorting the reality that the data represents. The IBCS “Check” principle advises against several specific practices that can lead to such distortions, including truncated axes, logarithmic scales used without clear indication, and inconsistent categorical axes.

Truncated Axes

Truncated axes, particularly on bar or line charts, can exaggerate differences between data points. This technique involves starting the axis at a value other than zero, which can make relatively small differences in data appear much larger than they are. While this can sometimes be done to highlight important variations, it often risks misleading the viewer.

For example, consider a chart showing year-over-year revenue growth. If the y-axis is truncated to start at $1 million rather than $0, the growth might appear more dramatic than it truly is, leading viewers to overestimate the company’s performance.

Illustration in R:

library(ggplot2)

# Data example
data <- data.frame(
  Year = c("2020", "2021", "2022"),
  Revenue = c(1.1, 1.3, 1.4) # In millions
)

# Truncated axis example
ggplot(data, aes(x = Year, y = Revenue)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  coord_cartesian(ylim = c(1, 1.5)) + # Keep data within limits
  labs(title = "Revenue Growth (Truncated Axis)",
       y = "Revenue (in millions)",
       x = "Year")

This code produces a bar chart with a truncated y-axis starting at $1 million. The resulting visualization exaggerates the growth in revenue, making a modest increase seem much more significant.

Correct Approach: To avoid misleading the audience, it’s generally better to start axes at zero, especially in bar charts where the length of the bars is meant to be proportional to the value they represent.

Illustration in R:

# Correct axis example
ggplot(data, aes(x = Year, y = Revenue)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  scale_y_continuous(limits = c(0, 1.5)) + # Axis starts at zero
  labs(title = "Revenue Growth (Proper Axis)",
       y = "Revenue (in millions)",
       x = "Year")

This version of the chart starts the y-axis at $0, providing a more honest representation of the revenue growth over time.

Logarithmic Scales with Different Magnitudes

Misleading Example: Logarithmic Scale Without Clear Indication

Let’s consider a dataset representing company revenues across several years. The revenues vary widely, from thousands to millions. A logarithmic scale can be useful here, but without proper indication, it can mislead viewers about the magnitude of differences.

Data Example:

# Example dataset with varying magnitudes
data1 <- data.frame(
  Year = c("2010", "2011", "2012", "2013", "2014", "2015"),
  Revenue = c(10^3, 10^4, 10^5, 10^6, 10^7, 10^8) # Revenues from $1,000 to $100,000,000
)

# Misleading log scale example
ggplot(data1, aes(x = Year, y = Revenue)) +
  geom_line(group = 1, color = "red") +
  scale_y_log10() + # Logarithmic scale applied without clear labeling
  labs(title = "Revenue Growth (Logarithmic Scale)",
       y = "Revenue",
       x = "Year")

Explanation: In this chart, the y-axis uses a logarithmic scale, but the labels and title do not clearly communicate this to the viewer. The impression given is that the changes in revenue are linear, which is misleading since each year represents a tenfold increase.

Proper Example: Logarithmic Scale with Clear Indication

To correctly use a logarithmic scale, it should be clearly labeled, and the viewer should be informed about the scale being used.

Proper Visualization:

# Properly labeled log scale example
ggplot(data1, aes(x = Year, y = Revenue)) +
  geom_line(group = 1, color = "blue") +
  scale_y_log10(labels = scales::comma) + # Clear logarithmic scale with labels
  labs(title = "Revenue Growth (Logarithmic Scale)",
       y = "Revenue (log scale)",
       x = "Year") +
  annotate("text", x = 4, y = 1e4, label = "Logarithmic Scale", size = 3, color = "blue")

Explanation: This version properly labels the y-axis to indicate that a logarithmic scale is being used. Annotations or additional explanations could further help viewers understand the exponential growth represented in the data.

Proper Example: Linear Scale for Direct Comparison

Using a linear scale can sometimes be more appropriate, especially when the goal is to show absolute differences between values rather than relative differences.

Proper Visualization with Linear Scale:

ggplot(data1, aes(x = Year, y = Revenue)) +
  geom_line(group = 1, color = "red") +
  scale_y_continuous(labels = scales::comma) + # Linear scale
  labs(title = "Revenue Growth (Linear Scale)",
       y = "Revenue",
       x = "Year")

Explanation: In this version, the y-axis uses a linear scale. This chart clearly shows the absolute differences in revenue over time. While it may be less effective at showing relative growth, it avoids the potential for misinterpretation that can come with a logarithmic scale. It’s particularly useful when the focus is on the actual increase in revenue rather than the rate of growth.

Categorical Axes with Age Buckets

Misleading Example: Unequal Bucket Widths

Let’s create a bar chart displaying age distribution across different age ranges. A misleading version might use buckets of varying widths, which can distort the representation of the data.

Data Example:

age_data <- data.frame(
  Age_Group = c("0-18", "19-25", "26-40", "41-60", "60+"),
  Count = c(500, 300, 1000, 700, 200)
)
ggplot(age_data, aes(x = Age_Group, y = Count)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  labs(title = "Age Distribution (Inconsistent Buckets)",
       y = "Count",
       x = "Age Group")

Explanation: In this chart, the age buckets are not equally spaced, which can mislead viewers into thinking that each bucket represents an equal range of years. For example, “26–40” covers 15 years, whereas “19–25” covers only 7 years, yet they are presented as equivalent.

Proper Example: Equal Bucket Widths

A proper approach would use equal-width buckets or clearly indicate that the buckets are of different sizes.

Proper Visualization:

# Adjusted data for equally wide buckets
age_data_proper <- data.frame(
  Age_Group = c("0-10", "11-20", "21-30", "31-40", "41-50", "51-60", "61-70", "71+"),
  Count = c(250, 250, 400, 600, 400, 300, 150, 200)
)

# Proper bar chart with consistent bucket widths
ggplot(age_data_proper, aes(x = Age_Group, y = Count)) +
  geom_bar(stat = "identity", fill = "steelblue") +
  labs(title = "Age Distribution (Consistent Buckets)",
       y = "Count",
       x = "Age Group")

Explanation: This version uses consistent 10-year buckets, which gives a more accurate representation of the distribution. Each bar represents an equivalent range, allowing for fair comparison across age groups.

By avoiding misleading practices such as improper use of logarithmic scales and inconsistent categorical bucket sizes, you ensure that your visualizations are clear and truthful. The examples provided highlight how these issues can arise and how to correct them, maintaining the integrity of your data presentation in line with the IBCS “Check” principle.

Avoiding Manipulated Visualization Elements

In data visualization, the elements used to represent data — such as bars, lines, and shapes — must be carefully crafted to avoid misleading the audience. Manipulated visualization elements can distort the viewer’s perception, leading to incorrect conclusions. The IBCS “Check” principle highlights the importance of using visualization elements that accurately and honestly represent the underlying data. This section will explore common pitfalls in the use of visualization elements and discuss how to avoid them.

Distorted Element Sizes

One common issue in data visualization is the use of elements whose sizes do not correspond proportionally to the data they represent. This is particularly problematic in area-based visualizations, such as pie charts or bubble charts, where the size of the visual element should reflect the magnitude of the data point.

Misleading Example: Consider a bubble chart where the area of the bubbles is used to represent the magnitude of data points. If the radius of the bubbles is scaled directly to the data, rather than the area, the visual representation will exaggerate differences between data points.

Proper Example: The correct approach is to scale the area of the bubbles proportionally to the data values, ensuring that visual differences match the actual data.

Inappropriate Use of 3D Effects

3D charts can sometimes make data appear more dynamic or engaging, but they often introduce visual distortions that make it difficult to accurately interpret the data. The use of 3D effects can obscure important details or exaggerate differences, making the visualization more decorative than informative.

Misleading Example: Consider a 3D bar chart where the depth and perspective distort the actual height of the bars.

Proper Example: A 2D bar chart is often more effective at accurately conveying differences between data points without introducing unnecessary visual complexity.

IMHO: 3D effects should be banned in BI and reporting.

Challenging Scaling with a Bar Chart

Misleading Example: Bar Chart with One Large Value

When one data point is significantly larger than the others, a standard bar chart can make it difficult to see and compare the smaller values.

# Example dataset with a large outlier
scaling_data <- data.frame(
  Category = c("A", "B", "C", "D", "E"),
  Value = c(10, 15, 20, 25, 500) # Notice the large value in Category E
)

# Misleading bar chart example
ggplot(scaling_data, aes(x = Category, y = Value)) +
  geom_bar(stat = "identity", fill = "red") +
  labs(title = "Bar Chart with Challenging Scaling",
       y = "Value",
       x = "Category")

Explanation:

  • In this bar chart, the large value in Category E completely overshadows the smaller values, making them almost invisible and difficult to compare. This visual dominance can lead to a skewed perception of the data, where the smaller categories appear insignificant.

Proper (IMO) Visualization: Waffle Chart

A waffle chart is a grid-based visualization where each cell represents a fixed unit (e.g., 1% of the total). It’s particularly effective when dealing with data that has a wide range of values because it allows the viewer to see the proportional representation of each category without being overwhelmed by a single large value.

library(waffle)

# Proper waffle chart example
waffle_data <- round(scaling_data$Value / sum(scaling_data$Value) * 100)  # Convert to percentages

waffle::waffle(waffle_data, rows = 10,
               colors = c("lightblue", "lightgreen", "lightpink", "orange", "darkred"),
               title = "Waffle Chart Showing Proportions")
Extra box after 100 is caused by rounding.

Explanation:

  • The waffle chart divides the total value into 100 squares, each representing 1% of the total. This allows each category to be seen in proportion to its contribution to the whole, regardless of how large or small it is.
  • Unlike the bar chart, the waffle chart gives a clear visual representation of each category’s size relative to the others, making it easier to understand the overall distribution without one category overwhelming the others.

Manipulated visualization elements can easily distort the message that data is meant to convey. Whether it’s through improperly scaled bubbles, the misleading use of 3D effects, or poorly handled scaling challenges, such practices can lead to misinterpretation and poor decision-making. By adhering to the IBCS “Check” principle, you ensure that your visual elements accurately represent the underlying data. This means scaling areas correctly, avoiding unnecessary and potentially confusing 3D effects, and choosing the right type of chart to convey the information clearly, even when dealing with data that varies widely in magnitude. By following these guidelines, you create visualizations that are not only honest and precise but also genuinely informative and trustworthy.

Avoiding Misleading Representation

In data visualization, the way data is represented can have a significant impact on how it is interpreted. Misleading representation can occur when visual elements distort the relationships between data points, exaggerate differences, or obscure important details. The IBCS “Check” principle advises against using representations that could mislead the viewer, whether intentionally or unintentionally. This section will explore common pitfalls in data representation and demonstrate how to avoid them.

Misuse of Area and Volume to Represent Data

One of the most common sources of misleading representation in data visualization is the misuse of area or volume to represent data values. For instance, using 2D shapes (like circles) or 3D objects (like cubes or spheres) to represent numerical data can be problematic because viewers tend to perceive the area or volume of these shapes as directly proportional to their size. However, as we discussed earlier, the area of a circle is proportional to the square of its radius, and the volume of a 3D object is proportional to the cube of its dimensions. This can cause significant distortions if not handled correctly.

Misleading Example: Let’s consider a scenario where we use circles to represent population sizes across different cities. If the radii of the circles are directly proportional to the population, the visual impression will exaggerate the differences between cities.

Proper Example: The correct approach is to scale the radius of the circles according to the square root of the population, ensuring that the area of each circle is proportional to the population it represents.

Data Example:

library(patchwork)
# Example dataset with city populations
population_data <- data.frame(
  City = c("City A", "City B", "City C"),
  Population = c(1000000, 2000000, 4000000) # Population in millions
)

# Misleading bubble chart example
imp = ggplot(population_data, aes(x = City, y = Population, size = Population)) +
  geom_point(shape = 21, fill = "lightblue") +
  scale_size_continuous(range = c(5, 20)) + # Radius scaled directly to population
  theme(legend.position = "none") +
  labs(title = "Misleading Representation of Population Sizes",
       y = "Population",
       x = "City")

# Proper bubble chart with area scaled to population
p = ggplot(population_data, aes(x = City, y = Population, size = sqrt(Population))) +
  geom_point(shape = 21, fill = "green3") +
  theme(legend.position = "none") +
  scale_size_area(max_size = 20) + # Ensuring the area scales properly
  labs(title = "Accurate Representation of Population Sizes",
       y = "Population",
       x = "City")

imp + p + plot_layout(ncol = 2)

Explanation:

  • In this chart, the size of each circle is determined by the population value. Since the size is mapped to the radius, the area of the circles does not accurately reflect the actual population differences. For example, the circle for City C (with a population of 4 million) will appear disproportionately large compared to City A (with 1 million), even though the population is only four times larger.
  • By using sqrt(Population) for the size aesthetic, the area of each circle now correctly represents the population. This makes the visual differences between cities proportional to the actual data, providing an accurate and honest representation.

Avoiding Misleading Representation on Maps

Maps are a powerful tool for visualizing geographical data, but they also come with their own set of challenges. The way data is represented across different regions can significantly influence how it is interpreted. A common pitfall is the use of color gradients on choropleth maps, which can exaggerate or understate differences between regions, leading to misinterpretation. This is especially problematic when visualizing percentage data, such as unemployment rates, where subtle differences might be magnified or diminished depending on the color scale used.

Let’s assume we’re displaying the unemployment rate for each state in a specific region (e.g., California, Utah, Nevada, Arizona, Colorado, and New Mexico). The improper visualization will use a gradient that can be misleading, while the proper visualization will use small pie charts to represent the percentage visually.

Data Preparation

We’ll start by creating a dataset with fictional unemployment rates for each of the selected states.

# Example dataset with unemployment rates for selected states
unemployment_data <- data.frame(
  State = c("California", "Utah", "Nevada", "Arizona", "Colorado", "New Mexico"),
  UnemploymentRate = c(7.8, 3.1, 6.4, 5.2, 4.0, 6.9) # Fictional data
)

# Mapping the state names to match map data
unemployment_data$State <- tolower(unemployment_data$State)

Improper Visualization: Gradient Choropleth Map

In this example, we’ll use a color gradient to represent the unemployment rate. This can be misleading because it might exaggerate or understate the differences between states, especially when the differences are relatively small.

library(ggplot2)
library(maps)

# Get the map data for selected states
states_map <- map_data("state", region = c("california", "utah", "nevada", "arizona", "colorado", "new mexico"))

# Improper gradient map
ggplot(unemployment_data, aes(map_id = State, fill = UnemploymentRate)) +
  geom_map(map = states_map, color = "black") +
  expand_limits(x = states_map$long, y = states_map$lat) +
  scale_fill_gradient(low = "lightblue", high = "darkblue") +
  labs(title = "Improper Representation: Unemployment Rate by State",
       fill = "Unemployment Rate (%)") +
  theme_minimal()

Explanation:

  • This choropleth map uses a gradient to show the unemployment rate across the selected states. However, the use of color alone can mislead viewers by making small differences seem more significant than they are, especially when using a broad color range.

Proper Visualization: Pie Charts for Each State

To provide a clearer and more precise visual representation, we’ll place small pie charts on each state to represent the unemployment rate. This approach allows the viewer to see the exact proportions, reducing the risk of misinterpretation.

library(ggplot2)
library(ggforce)  # For making pie charts on maps
library(maps)

create_pie_grob <- function(rate) {
  pie_values <- c(100 - rate, rate)  # Employed vs. Unemployed
  pie_data <- data.frame(
    category = c("Employed", "Unemployed"),
    value = pie_values
  )
  
  gg_pie <- ggplot(pie_data, aes(x = "", y = value, fill = category, colour = "black")) +
    geom_bar(stat = "identity", width = 1) +
    coord_polar(theta = "y") +
    scale_fill_manual(values = c("lightgreen", "red")) +
    theme_void() +
    theme(legend.position = "none")
  
  ggplotGrob(gg_pie)
}

# Base map
base_map <- ggplot(states_map, aes(x = long, y = lat, group = group)) +
  geom_polygon(fill = "lightgrey", color = "black") +
  coord_fixed(1.3) +
  theme_void() +
  labs(title = "Proper Representation: Unemployment Rate by State")

# Add pie charts to the map
for (i in 1:nrow(unemployment_data)) {
  state <- unemployment_data$State[i]
  rate <- unemployment_data$UnemploymentRate[i]
  
  # Get the center of the state
  state_center <- data.frame(long = mean(states_map$long[states_map$region == state]),
                             lat = mean(states_map$lat[states_map$region == state]))
  
  # Add pie chart at the center
  base_map <- base_map + 
    annotation_custom(grob = create_pie_grob(rate), 
                      xmin = state_center$long - 1.5, 
                      xmax = state_center$long + 1.5, 
                      ymin = state_center$lat - 1.5, 
                      ymax = state_center$lat + 1.5)
}

# Display the map
print(base_map)

Explanation:

  • In this visualization, small pie charts are placed on each state, showing the unemployment rate directly as a percentage. This approach makes it easier to compare the unemployment rates between states without relying on potentially misleading color gradients.
  • create_pie_grob Function: This function generates a pie chart for the given unemployment rate. It creates a small pie chart using ggplot2, which is then converted into a grob (graphical object) using ggplotGrob for placement on the map.
  • annotation_custom: This function is used to place the pie chart at the center of each state on the map. The size of the pie chart is adjusted for visibility.
  • Color Representation: The pie chart shows the proportion of employed (green) vs. unemployed (red), making it easy to interpret the unemployment rate visually.

Using a gradient to represent percentage data on maps can be misleading, particularly when the differences are subtle or when the scale isn’t intuitively understood by the viewer. By contrast, using small pie charts to directly represent percentages for each region offers a clearer and more accurate depiction of the data. This approach adheres to the IBCS “Check” principle by ensuring that visualizations are both informative and easy to interpret, minimizing the risk of misinterpretation.

Using Consistent Scales Across Visuals

One of the key principles of effective data visualization is the consistent use of scales across related charts. When multiple charts are used to compare different datasets, using inconsistent scales can lead to misleading interpretations and poor decision-making. The IBCS “Check” principle emphasizes the importance of maintaining consistent scales to ensure that viewers can accurately compare data across different visualizations.

The Importance of Consistent Scales

Inconsistent scales can drastically alter the perception of data. For example, two bar charts displaying sales figures for different products may appear to show similar performance, but if the y-axis scales are different, the charts might be hiding significant differences. This can occur when different charts are automatically scaled based on their data range, leading to misleading comparisons.

When charts are presented together, it is crucial that they use the same scale, especially when they represent the same units. This allows for an accurate visual comparison between datasets. Consistent scaling also applies to time series data, where inconsistent x-axes can distort the perceived timing of events or trends.

Example: Inconsistent vs. Consistent Scales in Bar Charts

Inconsistent Scales Example: Let’s consider two bar charts representing sales data for two different products over the same period. If each chart is scaled independently, the differences in sales might be exaggerated or minimized, leading to misinterpretation.

library(ggplot2)

# Example sales data for two products
product_a <- data.frame(
  Month = c("January", "February", "March", "April"),
  Sales = c(50, 60, 70, 90)
)

product_b <- data.frame(
  Month = c("January", "February", "March", "April"),
  Sales = c(10, 20, 30, 40)
)

# Inconsistent scales for Product A and Product B
p1 <- ggplot(product_a, aes(x = Month, y = Sales)) +
  geom_bar(stat = "identity", fill = "skyblue") +
  labs(title = "Product A Sales", y = "Sales", x = "Month") +
  theme_minimal()

p2 <- ggplot(product_b, aes(x = Month, y = Sales)) +
  geom_bar(stat = "identity", fill = "lightgreen") +
  labs(title = "Product B Sales", y = "Sales", x = "Month") +
  theme_minimal()

# Display the charts
library(patchwork)
p1 + p2 + plot_layout(ncol = 2)

Explanation:

  • In these charts, the y-axis scales are different. This can mislead viewers into thinking that Product B’s sales are comparable to Product A’s, when in reality, the scales hide the true difference in sales performance.

Proper Example: Consistent Scales Across Charts To provide a truthful comparison, the scales of the y-axes should be consistent across the two charts.

# Consistent scales for Product A and Product B
p1_consistent <- ggplot(product_a, aes(x = Month, y = Sales)) +
  geom_bar(stat = "identity", fill = "skyblue") +
  labs(title = "Product A Sales", y = "Sales", x = "Month") +
  theme_minimal() +
  ylim(0, 100)  # Setting the same y-axis scale

p2_consistent <- ggplot(product_b, aes(x = Month, y = Sales)) +
  geom_bar(stat = "identity", fill = "lightgreen") +
  labs(title = "Product B Sales", y = "Sales", x = "Month") +
  theme_minimal() +
  ylim(0, 100)  # Setting the same y-axis scale

# Display the charts with consistent scales
p1_consistent + p2_consistent + plot_layout(ncol = 2)

Explanation:

  • By using the same y-axis scale on both charts (ylim(0, 100)), viewers can immediately see that Product A’s sales are significantly higher than Product B’s. This consistent scaling enables a fair and accurate comparison.

Techniques for Handling Outliers and Scaling Issues

  1. Inset Zooming Composition:
  • An inset chart is a smaller chart embedded within a larger one, typically used to zoom in on a specific part of the data. This allows viewers to focus on important details that might be overshadowed by the overall scale of the data.
  1. Scaling Indicators:
  • Scaling indicators visually indicate that the scales of the compared charts differ, helping to prevent misleading interpretations. These indicators, like the dotted line in your image, make it clear that the two charts are on different scales.

Implementation in R

Let’s create a combined plot that includes both techniques: an inset zoom and scaling indicators.

Example Data

We’ll use fictional sales and profit data for this demonstration, similar to what’s depicted in the image.

library(ggplot2)

# Example sales and profit data
data <- data.frame(
  Month = factor(c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul"), levels = c("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul")),
  Sales = c(55, 50, 53, 54, 51, 55, 52),
  Profit = c(3, 2, 2.5, 3, 2.2, 3.1, 2)
)

# Base chart for Sales
p_sales <- ggplot(data, aes(x = Month, y = Sales)) +
  geom_bar(stat = "identity", fill = "grey20") +
  labs(title = "Sales in mUSD", y = NULL, x = NULL) +
  ylim(0, 100) +  # Scale is manually set for visual comparison
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5))

# Inset chart for Profit
p_profit <- ggplot(data, aes(x = Month, y = Profit)) +
  geom_bar(stat = "identity", fill = "grey20") +
  labs(title = "Profit in mUSD", y = NULL, x = NULL) +
  ylim(0, 10) +  # Scale is manually set for visual comparison
  theme_bw() +
  theme(plot.title = element_text(hjust = 0.5))

# Combine Sales and Profit with inset and scaling indicators using inset_element
combined_plot <- p_sales +
  inset_element(p_profit, left = 0.6, bottom = 0.6, right = 0.95, top = 0.95) # Adjust inset position and size


# Display the combined plot
print(combined_plot)

Explanation:

  • inset_element(p_profit, left = 0.6, bottom = 0.6, right = 0.95, top = 0.95): This function from the patchwork package is used to place the profit chart as an inset within the sales chart. The arguments (left, bottom, right, top) control the position and size of the inset.

This method using inset_element simplifies the placement of inset charts within ggplot2 plots while maintaining clarity and accuracy in your visualizations.

Using inset zooms and scaling indicators is an effective way to present data with vastly different scales in a single visualization. This approach adheres to the IBCS “Check” principle, ensuring clarity and accuracy in your data comparisons. These techniques help the audience understand the relationships between different datasets without being misled by scale differences.

Showing Data Adjustments Transparently

Transparency in data reporting is crucial, especially when adjustments such as inflation, currency conversion, or seasonal adjustments are applied to the data. These adjustments can significantly alter the interpretation of the data, and if not communicated clearly, they can lead to misunderstandings or misinterpretation. The IBCS “Check” principle stresses the importance of clearly indicating when and how data has been adjusted, ensuring that the audience can accurately understand the context and implications of the presented figures.

Importance of Transparency in Data Adjustments

Data adjustments are often necessary to make meaningful comparisons over time or across different regions. For example, when comparing financial data across years, it’s common to adjust for inflation to reflect real purchasing power rather than nominal values. Similarly, when comparing financial performance across countries, currency conversions might be necessary to provide a consistent basis for comparison. However, if these adjustments are not clearly communicated, the data can be misleading.

Transparency in these adjustments involves not only stating that an adjustment has been made but also explaining the method used and its impact on the data. This ensures that the audience understands the basis for the figures they are seeing and can interpret them correctly.

Example: Adjusting for Inflation

Let’s consider an example where we need to compare revenue over several years. The revenue values are adjusted for inflation to provide a more accurate picture of growth in real terms.

Data Example:

library(ggplot2)

# Example dataset: Nominal and inflation-adjusted revenue
revenue_data <- data.frame(
  Year = c(2015, 2016, 2017, 2018, 2019, 2020),
  Nominal_Revenue = c(100, 105, 110, 120, 130, 135),
  Inflation_Adjusted_Revenue = c(100, 103, 106, 112, 118, 120)  # Adjusted to 2015 dollars
)

# Plotting nominal and inflation-adjusted revenue
p_revenue <- ggplot(revenue_data, aes(x = Year)) +
  geom_line(aes(y = Nominal_Revenue, color = "Nominal Revenue"), linewidth = 1.2) +
  geom_line(aes(y = Inflation_Adjusted_Revenue, color = "Inflation-Adjusted Revenue"), linewidth = 1.2) +
  scale_color_manual(values = c("Nominal Revenue" = "blue", "Inflation-Adjusted Revenue" = "red")) +
  labs(title = "Company Revenue Over Time (Nominal vs. Inflation-Adjusted)",
       y = "Revenue (in millions)", x = NULL, color = "Legend") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

# Display the plot
print(p_revenue)

Explanation:

  • In this chart, both nominal and inflation-adjusted revenue are plotted over time. The nominal revenue line (in blue) shows the raw revenue values, while the inflation-adjusted revenue line (in red) reflects the values adjusted to 2015 dollars.
  • This clear visual distinction helps the audience understand how the company’s revenue has changed in real terms, accounting for inflation.

Example: Currency Conversion

When comparing data across different countries, currency conversion is often necessary. Let’s say we’re comparing the revenue of a company operating in both the United States and Europe, where the revenue needs to be converted from euros to U.S. dollars for consistency.

Data Example:

# Example dataset: Revenue in EUR and converted to USD
conversion_data <- data.frame(
  Year = c(2015, 2016, 2017, 2018, 2019, 2020),
  Revenue_EUR = c(80, 85, 88, 90, 95, 100),  # Revenue in millions of EUR
  Revenue_USD = c(88, 92, 95, 100, 104, 110)  # Converted to millions of USD (assume a conversion rate)
)

# Plotting revenue in EUR and converted to USD
p_conversion <- ggplot(conversion_data, aes(x = Year)) +
  geom_line(aes(y = Revenue_EUR, color = "Revenue in EUR"), size = 1.2) +
  geom_line(aes(y = Revenue_USD, color = "Revenue in USD (Converted)"), size = 1.2) +
  scale_color_manual(values = c("Revenue in EUR" = "green4", "Revenue in USD (Converted)" = "orange3")) +
  labs(title = "Company Revenue Over Time (EUR vs. USD Conversion)",
       y = "Revenue (in millions)", x = NULL, color = "Legend") +
  theme_minimal() +
  theme(plot.title = element_text(hjust = 0.5))

# Display the plot
print(p_conversion)

Explanation:

  • This chart shows the revenue in euros and the corresponding converted revenue in U.S. dollars. The lines clearly distinguish between the original and converted values, allowing the audience to see how currency conversion impacts the reported figures.
  • By showing both the original and converted data, the chart provides transparency, helping the viewer understand the adjustments made for currency differences.

Clearly indicating and explaining data adjustments, such as inflation adjustments or currency conversions, is essential for maintaining transparency and accuracy in data reporting. By visually distinguishing adjusted data from raw data and providing clear explanations of the adjustments, you help your audience understand the context and make informed decisions based on accurate and trustworthy information. The IBCS “Check” principle guides you to present these adjustments transparently, ensuring that your data visualizations are both informative and credible.

Conclusion

In this episode, we’ve delved into the “Check” principle of the IBCS SUCCESS framework, emphasizing the importance of maintaining accuracy, transparency, and integrity in data visualization. As we’ve seen, even small decisions in how data is presented can have a significant impact on how it is interpreted. By adhering to the guidelines outlined in the “Check” principle, you ensure that your data visualizations are both truthful and effective.

Key takeaways from this chapter include:

Avoiding Manipulated Axes:

  • Ensure that axes are not truncated, logarithmic scales are used appropriately, and categorical axes are consistent. This prevents exaggeration or minimization of differences, leading to a more accurate representation of the data.

Avoiding Manipulated Visualization Elements:

  • Use proper scaling for elements like bubbles or bars, avoid misleading 3D effects, and carefully handle scaling challenges, such as outliers. Properly scaled and well-chosen visual elements contribute to a more reliable interpretation of the data.

Avoiding Misleading Representation:

  • Choose visualizations that accurately represent the data. Avoid using area or volume incorrectly, and prefer simple, clear visualizations over complex, decorative ones that might distort the data.

Using Consistent Scales Across Visuals:

  • Maintain consistent scales across related charts to enable fair comparisons. Techniques like inset charts and scaling indicators can help manage differences in data magnitude without misleading the viewer.

Showing Data Adjustments Transparently:

  • Clearly communicate when data has been adjusted, whether for inflation, currency conversion, or other factors. Use visual cues and annotations to explain the adjustments and their impact on the data, ensuring that the audience understands the true meaning of the figures.

By following these best practices, you can create visualizations that not only convey the correct information but also build trust with your audience. The “Check” principle of the IBCS framework is about more than just avoiding errors — it’s about fostering a culture of transparency and precision in data communication.

As you continue to apply the IBCS standards in your reporting and BI work, remember that the integrity of your visualizations is paramount. Clear, accurate, and honest data presentation is the foundation of effective decision-making, and by rigorously “checking” your visualizations, you ensure that your insights are both credible and actionable.


Guarding Against Misleading Data was originally published in Numbers around us on Medium, where people are continuing the conversation by highlighting and responding to this story.

To leave a comment for the author, please follow the link and comment on their blog: Numbers around us - Medium.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)