Power BI lets you build custom charts with Python or R scripts using the Python visual and R visual in the Visualizations pane. You drag fields into the visual, Power BI passes them to your script as a table called dataset, and the image your script draws (with Matplotlib, seaborn or ggplot2) appears on the report page. They are ideal for statistical charts that native visuals cannot produce, but they come with real limits on interactivity, data size and sharing that you should understand before you rely on them.
When to use Python or R visuals
Native Power BI visuals are fast, interactive and easy for colleagues to edit. Choose a script visual only when it adds something the built-in options cannot:
- Statistical charts: distribution plots, box plots with custom whiskers, regression lines with confidence bands, correlation heatmaps.
- Specialized layouts: small multiples with full control, pair plots, or annotated charts for a publication.
- Reusing existing code: a data science team already has a Matplotlib or ggplot2 chart and wants it in the same report as the business KPIs.
If a bar, line, scatter or matrix answers the question, stay native. Our guide to choosing the right Power BI visual covers those options.
Setup: what you need on your computer
Power BI Desktop does not include Python or R. You install them separately and point Power BI to them.
- Install Python (from python.org or Anaconda) and the required packages:
pip install pandas matplotlib. Add seaborn if you plan to use it. - For R, install R and any packages you need, such as
install.packages("ggplot2"). - In Power BI Desktop, go to File > Options and settings > Options, then open Python scripting (or R scripting) and confirm the detected home directory.
- Restart Power BI Desktop if you changed the path.
Creating your first Python visual
- In the Visualizations pane, select the Py icon. The first time, Power BI asks you to enable script visuals; select Enable.
- Drag fields into the Values well, for example
Region,OrderDateandRevenue. - A script editor opens below the canvas with generated code that creates a pandas DataFrame called
datasetfrom your fields. - Write your plotting code beneath the generated lines and select the Run script button.
Here is a box plot of order revenue by region, a chart that shows spread and outliers rather than just totals:
# 'dataset' is created by Power BI from the fields in Values
import matplotlib.pyplot as plt
regions = sorted(dataset["Region"].dropna().unique())
data = [dataset.loc[dataset["Region"] == r, "Revenue"] for r in regions]
fig, ax = plt.subplots(figsize=(8, 4.5))
ax.boxplot(data)
ax.set_xticks(range(1, len(regions) + 1))
ax.set_xticklabels(regions)
ax.set_title("Order revenue distribution by region")
ax.set_ylabel("Revenue")
plt.tight_layout()
plt.show()
Power BI captures whatever is drawn on the default plotting device, so finish with plt.show() and do not save to a file or open a separate window.
The duplicate-rows trap
Power BI groups the fields you add, as with any visual set to "Don't summarize," so identical rows are collapsed into one before your script sees them. For a box plot or histogram this silently changes the result. Add a field that makes each row unique, such as OrderID or an index column created in Power Query, to keep every row.
The same chart as an R visual
R visuals work the same way: Power BI creates an R data frame called dataset, and your script draws a plot.
# 'dataset' is created by Power BI from the fields in Values
library(ggplot2)
ggplot(dataset, aes(x = Region, y = Revenue)) +
geom_boxplot() +
labs(title = "Order revenue distribution by region", y = "Revenue") +
theme_minimal()
Choosing between them is mostly about your team's skills. Python is more common among analysts who also automate reports; R and ggplot2 remain popular with statisticians.
Other ways to use Python in Power BI
Script visuals are not the only option. You can also run a Python script as a data source (Get data > Python script) or as a transformation step in Power Query, where the script receives the current table and returns a cleaned DataFrame. Those approaches put Python in the data preparation stage instead of the presentation stage, and the results feed ordinary, fully interactive native visuals. Keep in mind that scheduled refresh of Python-based queries in the service typically requires a personal gateway with Python installed, so plan for that before you build on it. If you only need a chart type that native visuals lack, also browse the certified custom visuals in AppSource, which stay interactive.
Limitations you must know
These limits come from Microsoft's documentation for Python visuals; R visuals have similar constraints. Check the official docs for the current values, since they can change.
| Area | What happens | Practical impact |
|---|---|---|
| Rows | Only the first 150,000 rows are used for plotting; the rest are dropped with a message | Aggregate or filter before plotting large tables |
| Input size | Input data is limited to 250 MB | Send only the columns the chart needs |
| Run time | Scripts that run longer than five minutes time out | Avoid heavy modeling inside a visual |
| Interactivity | The output is a static image; it responds to slicers and cross-highlighting, but you cannot click it to filter other visuals | Use native visuals for drill-down and tooltips |
| Resolution | Python visuals render at 72 DPI | Keep text large and charts simple |
Publishing to the Power BI service
In Power BI Desktop, script visuals use your local Python or R. In the service, Microsoft runs them on its own infrastructure with a supported set of packages, so a package you use locally may not be available online. Microsoft's documentation also ties service rendering to licensing (Pro or Premium Per User for viewing and interacting, or reports in Premium capacity workspaces), to region availability, and to tenant settings. Review the current requirements on Microsoft Learn and our Power BI licensing guide before you share a report that depends on script visuals. For reports shared through publish to web, script visuals are generally not supported, so test your sharing method first.
Best practices
- Prototype outside Power BI. The built-in editor is basic. Export a sample, build the chart in a Jupyter notebook, then paste the code in. See Charts in Python: Matplotlib vs Plotly for plotting patterns.
- Do the heavy lifting upstream. Clean and aggregate data in Power Query or with DAX measures so the script only draws.
- Match the report theme. Set font sizes and colors in your script to match the native visuals around it.
- Document the dependency. Note which packages and versions the report requires so colleagues can open and edit it.
Next steps
Pick one question your native visuals answer poorly, such as how order values are distributed by region, and build it as a Python or R visual in Power BI Desktop. Add a unique ID field, test it with slicers, then confirm it renders in the service under your organization's license before rolling it out to report consumers.
Watch: video lessons

Frequently asked questions
Are Python visuals in Power BI interactive?
Only partly. They redraw when slicers, filters or cross-highlighting change, but the output is a static image, so you cannot click it to filter other visuals or see tooltips.
Why does my Python visual show fewer data points than expected?
Power BI removes duplicate rows from the fields you add, and it only plots up to 150,000 rows. Add a unique ID field to keep every row, and aggregate large tables before plotting.
Do Python visuals work in the Power BI service?
They can, but the service uses its own supported packages and Microsoft ties rendering to licensing, region and tenant settings. Check the current requirements on Microsoft Learn before sharing.
Should I use Python or R visuals?
Both work in a similar way, so choose the language your team already knows. Python is common among analysts who automate reports, while R with ggplot2 is popular for statistical graphics.
Mark this lesson complete to track your rank progress.