What corrplot-ng Needs to Solve
Published on October 30, 2026 by Viliam Simko
The broader reasons for evolving corrplot are described in Beyond corrplot: Rethinking Correlation Visualization for the Next Decade. This article looks at a more practical question: what needs to be solved to make the same plotting functionality usable from different environments?
The goal is to keep the R package working while exploring interfaces for environments such as Python and the web. I also want a command-line tool that can generate a plot without requiring an R installation. These are directions we are working towards, not a claim that all of these interfaces are already available.
The problem with separate implementations
It would be possible to build a Python version, a web version, and a command-line program independently. Each could accept its own inputs and produce a correlation plot. The problem would come later: they could slowly start behaving differently.
For example, they might handle missing values in different ways, order variables differently, or make slightly different decisions about colours, labels, and layout. A user could get different results from the same data depending on which interface they used. Fixing a plotting issue in one implementation would not automatically fix it in the others.
Maintaining several copies of the same plotting logic would also mean more work for every future change. That is not a good trade-off for a project maintained with limited time.
The approach I am exploring is to keep the decisions that define a plot in one shared implementation. The surrounding interfaces should translate the conventions of their environment into inputs for that shared part, rather than reimplementing the plotting rules themselves.
Different environments need different interfaces
Sharing the plotting logic does not mean forcing every user to work in the same way.
An R user should be able to continue working with matrices, data frames, and familiar R conventions. A Python interface should feel like a Python library, not like an R API wrapped in another language. A command-line tool should be useful in scripts and automated jobs: it should accept data from files, report errors clearly, and write its output without starting R.
A web integration has different needs again. It may need to pass data through a service or display a generated image in a browser. We have not yet decided which web-facing interfaces make the most sense, so it would be premature to promise a particular application or framework.
The important point is that these interfaces can differ where their environments require it, while producing plots according to the same underlying rules.
Compatibility means more than keeping function names
The existing R package has users with established scripts and reports. Some workflows also rely on base R graphics: after drawing a corrplot, they may add labels, lines, or points with functions such as text(), segments(), or points().
A replacement could accept the same function arguments and still break those workflows if it draws in a different way or changes how graphics state is handled. Visual similarity alone is not enough.
For that reason, compatibility needs to be tested against real usage, not inferred from matching function names. The existing package is an important reference for expected behaviour. We need to identify which behaviours must remain unchanged, which differences are acceptable in other environments, and where an explicit compatibility layer is needed.
The aim is not to make Python or CLI users inherit every detail of the R interface. It is to keep the R experience dependable while allowing other interfaces to feel natural.
Installation is part of the design
A shared implementation is only useful if people can install and run it without fighting their environment.
This is particularly important for the command-line goal. If generating a plot requires a working R installation, the CLI has not solved the problem it was meant to solve. The same applies to Python: installation should fit normal Python workflows rather than require users to manually assemble a complicated toolchain.
There are several practical questions behind this. Can the implementation be built on the operating systems people use? How difficult is it to package for each environment? Does it introduce large runtime dependencies? Can we distribute ready-to-use binaries where that makes sense? These concerns can matter more to adoption than a small difference in execution speed.
I have been using prototypes to explore possible approaches, including Python, C++ with Rcpp, and Rust with rextendr. They help test integration, packaging, and maintenance costs. They are experiments, not three products, and the final implementation choice is still open.
Decide through working examples
Rather than settle every architectural question up front, I want to use small working examples to test the assumptions.
A useful early check is whether the same input can produce equivalent output through the R package and a standalone command-line program. Another is whether a Python caller can use the shared functionality without needing to know about the implementation language. We also need tests for missing values, unusual inputs, larger matrices, and the details of existing R workflows.
Performance matters, but benchmarks only tell part of the story. A fast implementation that is difficult to install, unreliable across platforms, or incompatible with established scripts would not be a good result. The benchmark work is one part of the evaluation; it does not replace testing the actual user experience.
The current experiments, implementation notes, and test plans are available in the corrplot-ng repository, including the architecture notes and testing strategy.
There are still open decisions, and the interfaces will become clearer as the prototypes are tested. For now, the work is focused on a few concrete requirements: keep the R package dependable, avoid duplicating plotting logic, make a standalone CLI possible without R, and find practical ways for other environments to use the same functionality.