PSA: Scaling Graphs in Dash

Hello everyone,

I just wanted to share a quick tip on something I found quite useful and was unable to find any reference to in the docs (could definitely be missing it!).

There are plenty of good posts and docs when it comes to sizing your plotly graphs. However, I was at a loss how to handle this for smaller, mobile oriented layouts.

By default, your graphs (and entire layout) will be scaled for mobile layouts by rendering content according to a larger, virtual viewport then shrinking the content down. However, when trying to set the meta tags for a purpose built mobile layout, I was at a loss for how to emulate this scaling for just the graphs. If you’re unsure what I’m talking about, this post is highly informative.

It turns out to be relatively simple! Just modify the “.dash-graph” class’s “zoom” property. The following css code improved my mobile layout dramatically as shown below:

.dash-graph {
  zoom: 0.45;
}

@media (min-width: 475px) {
  .dash-graph {
    zoom: 0.6;
  }
}

@media (min-width: 768px) {
  .dash-graph {
    zoom: 0.85;
  }
}

@media (min-width: 1024px) {
  .dash-graph {
    zoom: 1;
  }
}

Before zoom css:

After zoom css:

Hopefully someone else finds this useful!

8 Likes

nice one cheers for sharing this, css is so much fun!

2 Likes

A somewhat disappointing update. As you change the zoom level, the zoom/pan interactions have a progressively larger offset from where the mouse/touch actually is as demonstrated in the video below. The first half of the video shows the large offset when .dash-graph is zoomed out as compared to the normal behavior in the second half.

plotly_gif

The transform: scale() property does not have this unintended offset effect, but I lose the dynamic nature of the page that the zoom property allows (i.e. the graph no longer fills all the available space as it is always scaled to a fraction of the available space). If anyone has a workaround, let me know!

Nice trick! Unfortunately not supported in Firefox at the moment :confused:

1 Like

My favorite tip for mobile graphs is to:

  1. Reduce the margins of the graph
  2. Move the legends within the graph
  3. Set automargin

The margins are “fixed width” whereas the plot is “variable width”, so the plot area will shrink on small screens but the margins will stay disproportionally large. However, with small margins, the graphs can look great no matter what screen width.

image

1 Like

Hey @chriddyp, really appreciate the response! These tips are super helpful, but I have a couple of quick follow-up questions.

First off, is there a way to modify these properties using CSS? Ideally, I would just shrink the margins and move the legend at a certain screen size with media queries, but I haven’t had any luck changing margins in the browser developer tools. I have even less of an idea of how to move the legend dynamically.

My other question is in regards to changing the font size of plot elements. I can change font size of specific elements (e.g. title, legend title, etc.) in the developer tools but it requires modifying the root element in each plot element’s container. I could potentially target these using something like the :last-child pseudo selector, but wanted to see if you had any other ideas. For example, it would be great if I could set all the graph font size’s in rem units as I could dynamically scale this with all the other content in the page using CSS global variables.

Thanks again for taking the time to help with getting a proper mobile layout!

Another update. Thanks to the tip from @chriddyp, I’m much closer to having a fully functional mobile layout that works for all browsers (as mentioned by @RenaudLN ).

I’ve set automargin for the x and y axes as well as manually reduced some of the margins. As far as I know, plot margins can only be set once for all screen sizes in python.

Additionally, I moved the legend into the vertical margins instead of the horizontal margins. I did not move it inside the graph as suggested due to the modular nature of some of my graphs where the legend can grow quite large and obscure a lot of the data. I also have additional annotations on some graphs that I decided to place under the title to act as a subtitle. As far as I know, legends can also only be set once for all screen sizes in python so you must select a location that looks decent for all screen sizes.

Before:

After:

This can be made to look decent on all screen sizes when you target the title (className=“gtitle”) and annotation (className=“annotation-text”) font size with media queries. However, I’ve ran into two new issues shown in the gifs below:

Issue 1: The legend is oriented horizontally but randomly goes vertical. This can be triggered a number of ways (e.g. resizing the screen, zooming, etc.) and appears to require continuous screen resizes or a full page refresh to fix.
Screen Recording 2021-10-27 at 6.59.33 PM

Issue 2: At certain screen sizes (seems to be dependent on how many parameters I’ve selected in the multi-dropdown), the graph does not resize properly as the window grows. However, it seems to usually correct if I shrink the window back a bit as shown below (Issue 1 also on display in second gif during the screen resize).
vid3

At a bit of a loss on how to tackle either of these remaining issues. If anyone has any thoughts on next steps or has seen something similar before, let me know!

Hopefully this isn’t breaking any rules by continuing to reply to my own thread. I wanted to confirm that both of the issues I mentioned are a bug related to using a horizontal legend.

Issue 1 was recently reported on the github repo so hopefully it will be addressed soon.

Issue 2 has not been mentioned anywhere as far as I can tell and occurs on all my plots that use a horizontal legend. It is also a more serious bug that discourages me from using horizontal legends at all. Hopefully both issues can be addressed in a future update for improved mobile layouts.

For now, I’ve taken the approach of having a transparent, vertical legend. After shrinking the font size of the graph title, axis titles, and axis ticks with CSS media queries, automargin does not appear to recalculate the margins resulting in some wasted space. Additionally, I haven’t found any way of reliably resizing the legend with CSS so I leave the original font size so it looks good on desktops.