Data Visualization in pure Mojo: canvas_mojo and dataviz_mojo

Hey everyone…first post here, but we may have interacted in some other open-source community before (Python, Julia, R, Streamlit, etc.) :slight_smile:

As part of taking stock of what I actually know as a software developer in the LLM world, I went down the rabbit hole of “How are graphics actually rendered on a computer?” I purposely tried to approach this question from a first-principles exploration, which is why I didn’t want to use JavaScript, tried not to link to Cairo or other C libraries…and the following two packages are what arose from that!

canvas_mojo: a package that focuses on the lower-level pieces of images: how do you draw things at the pixel level, is there a specific number of default shapes to provide, what is the difference between raster (BMP, PNG) and vector graphics. Stuff like that. It does currently link to fontconfig, though that might be removed soon.

In order to validate the feature completeness of canvas_mojo, I then created dataviz_mojo. This is a higher-level, grammar-of-graphics flavored plotting library. At its most basic, there is a Plot object that can be modified in various ways to make a chart, and 40+ “quickplot” type functions for common charts like Bar, Scatter, Pie, and so on.

I wanted to post this now for any feedback, before spending too much more time on it. If this is something that interests you, I’d love any comments, a test-drive of the software and filing GitHub issues that come up, and even actual collaborators.

Currently, the code is heavily Claude-flavored, but I think it’s still pretty reasonable for a human to understand. If not, make a PR of some kind :smiley:

Best,
Randy

I ran into rerun written in rust that compiles to WASM. My dream is to accelerate Holoviz (Bokeh, Datashader, Matplotlib) stack in Mojo and these are super cool to read through.

There was someone who wrote a FFI to Cairo in Mojo but a full rewrite seems like it would benefit more from the magic of Max and Mojo.

Where do you see these projects going?

Do you think it would be hard to add geospatial plots as well?

I actually started by using the cairo_mojo package, which seems to work great. But I couldn’t get past “Is something written 20+ years ago and linked against really the best way to do this?” And of course with LLM help, it didn’t take much to rebuild the necessary functionality in pure Mojo.

As far as where this ends up going…I like the idea of Mojo as a new language to do (new) things a new way (just like Julia before it). Python is fine, but there’s nothing exciting about it to me. All of the innovation in the Python world is just linking out to other compiled libraries or bolting on features that aren’t quite as good as other more modern languages.

So someone might go back and accelerate the Python libraries you listed, but it won’t be me :rofl:

As far as geospatial goes, I’d love to get there soon. At a previous company, we worked with a lot of GPU-rendered geospatial plots, so I have some prior art to borrow from. I’d need to survey a bit more of what is already available in Mojo (need a dataframe/geodataframe library I think, not sure about what else)

Python is a scripting language that allows for expressive programming which is why Mr. Lattner and company decided to make Mojo a superset.

Being able to hook into the rich existing ecosystem of Python packages is at the very least a short to medium term goal of both Mojo and most every other package I have seen.

Appreciate your work :slight_smile:

Well done, thanks for this ! :partying_face:
That’s an really useful package that comes with many features.
It is easy to use, well done again :sparkles:

that’s amazing, one of my wishes is GoG system for mojo Like ggplot or seaborn.objects but also benefits from the native code execution and GPU capabilities of mojo, lots of fields would benefit from this and it may push the language forward the same way that Makie did for Julia or matplotlib for Python. I actually wrote mojo_bindgen and Cairo bindings for that reason.

IMO It would be nice to have a dataviz system in mojo but think the biggest win for mojo would be in GPU acceleration, several really good systems exist for general plotting in other langauges but the suffering starts with large data, programmtic ETL+plotting pipelines, simulations .. etc it would be nice to have a vulkan or WGPU backend and also to structure dataviz to be backend indepedent so it can adopt a holoviz-like shading strategy or detailed vector graphics depending on the workload.

Sure, it just isn’t one of my goals. Until someone hires me to write Python again, it will just be something I know but don’t particularly enjoy :slight_smile:

Thanks! Right now, it’s still a bit tedious without having an automatic display mechanism via CLI or Jupyter or whatever, but I’ve been thinking about fixing that problem as well.

This package is somewhat set up for that, in that canvas_mojo has a trait defined for DrawTarget. So to the extent that any of those other backends conform to that, then they will be able to work with dataviz (at least, in theory, there’s always something that doesn’t work like you think it should!)

I’ve made a ton of updates to both packages in the past week, most noticeable on dataviz. More chart types and API refinement and tons of work on the docs. I hope you’ll take a look and file any issues for improvements you’d like to see :slight_smile:

Any idea how this implementation compares to something like Matplotlib for static plots in terms of speed sir?

I don’t, but I’ve been spending a bunch of time on the canvas side to optimize performance, so I’m hoping it compares favorably

I’d be curious to see especially for vector-based rasterizing like wind barbs and contours which Matplotlib/Cairo really struggles. Great work and hopefully I can get on it soon as well.

If you can point me to a public example, I’d love to try it out and see for myself

matplotlib.pyplot.barbs — Matplotlib 3.11.1 documentation
Wind barbs — Matplotlib 3.11.1 documentation

matplotlib.pyplot.contourf — Matplotlib 3.11.1 documentation
Contour plot of irregularly spaced data — Matplotlib 3.11.1 documentation

Obviously the bigger the number of barbs or larger the contours the slower it is.