Power-bi-agentic-development r-visuals
R visual creation and ggplot2 patterns for PBIR reports. Automatically invoke when the user mentions "R visual", "ggplot2", "ggplot in Power BI", or asks to "create an R visual", "add an R chart", "write an R visual script", "inject an R script into Power BI".
git clone https://github.com/data-goblin/power-bi-agentic-development
T=$(mktemp -d) && git clone --depth=1 https://github.com/data-goblin/power-bi-agentic-development "$T" && mkdir -p ~/.claude/skills && cp -r "$T/plugins/reports/skills/r-visuals" ~/.claude/skills/data-goblin-power-bi-agentic-development-r-visuals && rm -rf "$T"
plugins/reports/skills/r-visuals/SKILL.mdR Visuals in Power BI (PBIR)
Report modification requires tooling. Two paths exist:
CLI (preferred) -- use thepbircommand and thepbirskill. Install withpbir-clioruv tool install pbir-cli. Check availability withpip install pbir-cli.pbir --version- Direct JSON modification -- if
is not available, use thepbirskill (pbip plugin) for PBIR JSON structure and patterns. Validate every change withpbir-format.jq empty <file.json>If neither the
skill nor thepbir-cliskill is loaded, ask the user to install the appropriate plugin before proceeding with report modifications.pbir-format
R visuals execute R scripts (primarily ggplot2) to render static PNG images on the Power BI canvas. ggplot2 is the preferred library -- its grammar of graphics approach produces clean, publication-quality statistical visualizations with less code. R is particularly strong for statistical visualizations.
Visual Identity
- visualType:
scriptVisual - Data role:
(columns and measures, multiple allowed)Values - Data variable:
(data.frame, auto-injected)dataset - Row limit: 150,000 rows
- Output: Static PNG at 72 DPI -- no interactivity
Workflow: Creating an R Visual
Step 1: Add the Visual
Create the visual.json file manually (see
pbir-format skill in the pbip plugin for JSON structure) with visualType: scriptVisual, field bindings for the columns and measures you need (use Values:Table.Column or Values:Table.Measure format), and position/size as required.
Step 2: Write the Script
library(ggplot2) p <- ggplot(dataset, aes(x=Date, y=Sales)) + geom_col(fill="#5B8DBE") + theme_minimal(base_size=12) + theme(panel.grid.major.x=element_blank()) print(p) # MANDATORY for ggplot2
Critical rules:
is mandatory for ggplot2 objects -- they do not auto-display in Power BIprint(p)
is auto-injected as a data.frame; do not create itdataset- Access columns by index (
) to avoid name escaping issuesdataset[,1] - Use backticks for column names with spaces:
dataset$`Order Lines`
Step 2b: Review
Before presenting the script to the user, dispatch the
r-reviewer agent to validate correctness and provide design feedback.
Step 3: Inject the Script
Set the script content in the visual's
objects.script[0].properties.source literal value (see PBIR Format section below).
Escaping rules for visual.json injection:
The script must be encoded as a single-quoted DAX literal string inside
expr.Literal.Value:
- Newlines in the script become
in the JSON string\n - Double quotes inside the script (e.g.,
) become"#5B8DBE"
in the JSON string\" - The entire script is wrapped in single quotes:
'library(ggplot2)\n...\nprint(p)' - See
for a complete real-world visual.json showing this encodingexamples/visual/
Step 4: Validate
Validate JSON syntax with
jq empty <visual.json> and inspect the visual.json to confirm script content and field bindings.
PBIR Format
Scripts are stored in
visual.objects.script[0].properties:
{ "source": {"expr": {"Literal": {"Value": "'library(ggplot2)\\n...\\nprint(p)'"}}}, "provider": {"expr": {"Literal": {"Value": "'R'"}}} }
Identical structure to Python visuals except
visualType is scriptVisual and provider is 'R'.
Supported Packages
Power BI Service (R 4.3.3)
| Package | Version | Purpose |
|---|---|---|
| ggplot2 | 3.5.1 | Grammar of graphics |
| dplyr | 1.1.4 | Data manipulation |
| tidyr | 1.3.1 | Data tidying |
| ggrepel | 0.9.5 | Non-overlapping labels |
| patchwork | 1.2.0 | Compose multiple plots |
| cowplot | 1.1.3 | Publication-quality plots |
| corrplot | 0.94 | Correlation matrices |
| viridis | 0.6.5 | Color scales |
| RColorBrewer | 1.1-3 | Color palettes |
| forecast | 8.23.0 | Time series forecasting |
| pheatmap | 1.0.12 | Heatmaps |
| treemap | 2.4-4 | Treemaps |
| lattice | 0.22-6 | Trellis graphics |
~1000 CRAN packages available. Not supported: packages requiring networking (RgoogleMaps, mailR).
Full package list: https://learn.microsoft.com/power-bi/connect-data/service-r-packages-support
Desktop
Any locally installed R package works without restriction. R must be installed separately.
Best Practices
- Always call
-- ggplot2 objects require explicit printingprint(p) - Guard against empty data --
if (nrow(dataset) == 0) { plot.new(); text(0.5, 0.5, "No data") } - Use index-based column access --
avoids name escaping issuesdataset[,1] - Use
-- clean aesthetic that works well with Power BItheme_minimal() - Factor categorical variables -- control sort order explicitly with
factor() - Use hex colors matching the report theme
- Set margins --
to prevent clippingplot.margin=margin(t, r, b, l) - Keep scripts concise -- 5-min timeout Desktop, 1-min Service
Limitations
| Constraint | Desktop | Service |
|---|---|---|
| Output | Static PNG, 72 DPI | Static PNG, 72 DPI |
| Timeout | 5 minutes | 1 minute |
| Row limit | 150,000 | 150,000 |
| Output size | 2 MB | 30 MB |
| Networking | Unrestricted | Blocked |
| Gateway | Personal only | Personal only |
| Cross-filter FROM | Not supported | Not supported |
| Receive cross-filter | Yes | Yes |
| Publish to web | Not supported | Not supported |
| Embed (app-owns-data) | Ending May 2026 | Ending May 2026 |
Script Structure Template
library(ggplot2) # 1. Guard against empty data if (nrow(dataset) == 0) { plot.new() text(0.5, 0.5, "No data available", cex=1.5) } else { # 2. Data preparation (index-based access) df <- data.frame( category = dataset[,1], value = dataset[,2] ) # 3. Create visualization p <- ggplot(df, aes(x=reorder(category, -value), y=value)) + geom_col(fill="#5B8DBE", width=0.7) + theme_minimal(base_size=12) + theme( panel.grid.major.x = element_blank(), axis.title = element_blank() ) # 4. Render print(p) }
R vs Python Comparison
| Aspect | R () | Python () |
|---|---|---|
| Primary library | ggplot2 | matplotlib |
| Render call | | |
| Column access | or | or |
| Empty guard | | |
| Factor control | | |
| Runtime (Service) | R 4.3.3 | Python 3.11 |
When to Use R Visuals
R visuals are the preferred choice for statistical and analytical visualizations, particularly where R's statistical ecosystem excels. Use R visuals when you need:
- Distribution analysis (violin, ridgeline, density, boxplot)
- Statistical modeling (regression, correlation, ANOVA)
- Publication-quality analytical charts with ggplot2
- Packages like forecast, corrplot, pheatmap that have no Python equivalent of equal quality
Output is static PNG -- no cross-filtering FROM the visual, no hover/tooltip interactivity. Use Deneb instead for interactive custom visuals. Use SVG measures for simple inline graphics in tables/cards.
References
-- R Graph Gallery examples organized by chart type (distribution, correlation, ranking, evolution, flow)references/community-examples.md
-- Common ggplot2 chart patterns (bar, donut, line, heatmap, bullet)references/ggplot2-patterns.md
-- Standalone R scripts (bar-chart, trend-line) -- ready to inject into visual.json after escapingexamples/script/
-- PBIR visual.json: bullet chart with conditional coloring, error handling, and extensive escapingexamples/visual/bullet-chart.json
-- PBIR visual.json: horizontal bar with PY comparison lines and colored account labelsexamples/visual/bar-chart.json
-- PBIR visual.json: area chart with ribbon plot and month factor handlingexamples/visual/trend-line.json
Fetching Docs
To retrieve current R visual / package support docs, use
microsoft_docs_search + microsoft_docs_fetch (MCP) if available, otherwise mslearn search + mslearn fetch (CLI). Search based on the user's request and run multiple searches as needed to ensure sufficient context before proceeding.
Related Skills
-- Layout and design best practicespbi-report-design
-- Python Script visuals (same concept, different language)python-visuals
-- Vega/Vega-Lite visuals (interactive, vector-based alternative)deneb-visuals
-- SVG via DAX measures (lightweight inline graphics)svg-visuals
(pbip plugin) -- PBIR JSON format referencepbir-format