Repository: plotly/plotly.py

Issue:
Add white templates with axes lines, tickmarks, and different color rotation
Would you consider adding two templates with axis lines, tickmarks, and white background (similar to "xticks" in seaborn)? I believe this is a rather common style in various plotting libraries that also looks good in print and it would be nice to have it easily accessible, especially when teaching so that custom templates need not to be explained early on.

To illustrate what I mean

![image](https://user-images.githubusercontent.com/4560057/67139506-e8712c00-f205-11e9-8de0-91f93aa330e0.png)

And with gridlines

![image](https://user-images.githubusercontent.com/4560057/67139524-18203400-f206-11e9-9c94-7948b1523f51.png)

I also changed the color rotations to D3, viridis, and RdBu, which are common defaults elsewhere. Below is the code I used to create the first figure, it is not complete with the figure specific template properties that are in the other default templates but gives an idea of what I am referring to.

```python
go.layout.Template(
    layout=go.Layout(
        hovermode='closest',
        hoverlabel_align='left',
        plot_bgcolor='white',
        paper_bgcolor='white',
        font_size=13,
        xaxis=dict(showline=True, ticks='outside', showgrid=False,
                   linewidth=1.5, zeroline=False),
        yaxis=dict(showline=True, ticks='outside', showgrid=False,
                   linewidth=1.5, zeroline=False),
        colorway=px.colors.qualitative.D3,
        colorscale=dict(sequential=px.colors.sequential.Viridis,
                        diverging=px.colors.diverging.RdBu), 
    )
)
```



Discussion:
This makes sense, and it's also quite close to the previous default/`"none"` built-in template... We could maybe break this apart into some "aspect"-like templates that could be layered? Like a `"nogrid"` and `"outsideticks"` and then you could get what you're looking for with `"none+nogrid+outsideticks"` or something?
I like the flexibility in combining granular templates like that, and it makes it easier to remember templates if the name indicates what they do. I would be a little worried about about clarity and verbosity when around 4-5 templates are combined, e.g. `'none+axislines+nogrid+nozero+outsideticks+vibrantcolors'`. Maybe it would be worth adding one with that (or a similar) combination in addition to the granular ones?
I'm pretty open to adding new templates, I mostly want them to be "more different" from the existing defaults... How different are what are you proposing from the existing `"none"` template? I can mostly see the outside ticks and the yes or no gridlines, but maybe there are other aspects that are important to you?
I guess one thing that comes to mind from looking at this is that maybe we need an additional `.update*` method that targets *both* x and y axes, to cut down on repetition of this kind?

![image](https://user-images.githubusercontent.com/203523/67163382-ff597080-f322-11e9-8255-3444e0ce3877.png)

In addition to what you mentioned, I think the color rotations and slightly larger fonts are nice to set once in the default. I also want to experiment with having the background of the hover popup in white for all marker instead of the same color as the marker, but I haven't gotten there yet. 

Eventually, I think it would be helpful if the subplot column titles and legend could have the `species=` part removed via the template instead of by updating the traces manually for each plot (which is what I understood from a separate answer you gave regarding the legend, not sure if it is at all possible for the column titles, but I'm still new to plotly and express so I'm probably missing something). 
> background of the hover popup in white for all marker instead of the same color as the marker, but I haven't gotten there yet.

That's pretty easy, there's an attribute for that in the `layout`

> Eventually, I think it would be helpful if the subplot column titles and legend could have the species= part removed via the template

that's not going to be possible at all via `layout.template` as it's not something that maps to a single figure attribute, although it seems to be a popular enough request that we may end up just adding an additional kwarg for that to all PX methods, or a PX-level overrideable default or something.

I just held a short Plotly express tutorial for a dozen people from my lab and it was very well received! People found it intuitive and powerful! Participants were beginners to programmatic data analysis and visualization.

One thing that did come up was that many didn't like the default grey backgrounds (probably because it is uncommon in my field, biomed). When we switched to white backgrounds (the `none` template), the lack of axes lines (and occasional appearance of zerolines depending on the data range) were unexpected and confusing, especially when working with facets since the subplots float together without any clear separator between them. To illustrate this point, compare this

```python
px.scatter(tips, 'total_bill', 'tip', facet_col='smoker', facet_row='day',
           template=axes_lines, range_x=(1, 40), width=600)
```

![image](https://user-images.githubusercontent.com/4560057/67611673-6d050280-f750-11e9-9da5-25f1fbda3e87.png)

with this

```python
px.scatter(tips, 'total_bill', 'tip', facet_col='smoker', facet_row='day',
           template=axes_lines, range_x=(1, 40), width=600)
```

![image](https://user-images.githubusercontent.com/4560057/67611688-945bcf80-f750-11e9-9047-444cb0dc945e.png)

(note that I changed the axes lines to `1` instead of `1.5` from what I suggested initially, I think these thinner lines looks better)

My opinion is that tickmark labels and data points are noticeably more "anchored" in the second plot, whereas in the first they appear to float around more. Based on this and what I wrote previously, I think the addition of a white template (either with or without gridlines), with axes lines, and without zero lines (and changing the color to something that looks good on white, such as D3), would be a welcome addition. Happy to PR a suggestion or discuss further.

---

> that's not going to be possible at all via layout.template as it's not something that maps to a single figure attribute, although it seems to be a popular enough request that we may end up just adding an additional kwarg for that to all PX methods, or a PX-level overrideable default or something.

A px default would be great for these! I would even suggest that the default behavior is to omit the column names (definitely in the color legend and preferably in the subplot title as well). In my experience this is the most commonly desired behavior (but I of course don't have any data to back this up...).

I saw in one of your comments elsewhere that one of the reasons for the current behavior was to handle cases such as when you have a column, say `smoker`, with `Yes/No` values. I would be inclined to believe that this is rarer than having a column with labels, and also easy to change to labels (`smoker/non-smoker`) if desired (or of course with a default px option). What do you think about this?
Thanks for the candid feedback! As I said, I'd be open to a PR with a new template :) The screenshots above look a lot like the Seaborn `style="ticks"` look so we could call it `seaborn_ticks` unless it sometimes behaves quite differently.

With respect to the PX `col=val` labelling, this probably belongs in a different issue, as it cannot be addressed in a template, but my feeling is that I like the way Seaborn does it, with `col=val` on the facet labels but not in the legend. Today plotly.js doesn't support legend titles, but when it does we will likely remove this from the trace names, which will address most people's concerns. See https://github.com/plotly/plotly.js/issues/276 for the legend title issue.
Heads-up: 4.3 is coming out this week! Last call for PRs for this release is getting close ;)

Resolving patch:
diff --git a/packages/python/plotly/plotly/io/_templates.py b/packages/python/plotly/plotly/io/_templates.py
--- a/packages/python/plotly/plotly/io/_templates.py
+++ b/packages/python/plotly/plotly/io/_templates.py
@@ -37,6 +37,7 @@ def __init__(self):
         default_templates = [
             "ggplot2",
             "seaborn",
+            "simple_white",
             "plotly",
             "plotly_white",
             "plotly_dark",
diff --git a/packages/python/plotly/templategen/definitions.py b/packages/python/plotly/templategen/definitions.py
--- a/packages/python/plotly/templategen/definitions.py
+++ b/packages/python/plotly/templategen/definitions.py
@@ -2,6 +2,7 @@
 from templategen.utils import initialize_template
 from .utils.colors import colors
 import colorcet as cc
+import plotly.express as px
 
 # dict of template builder functions
 # This way we can loop over definitions in __init__.py
@@ -73,6 +74,82 @@ def ggplot2():
 builders["ggplot2"] = ggplot2
 
 
+def simple_white():
+    # Set colorbar_common
+    colorbar_common = dict(
+        outlinewidth=10,
+        tickcolor=colors["gray14"],
+        ticks="outside",
+        tickwidth=2,
+        ticklen=8,
+    )
+
+    # Common axis common properties
+    axis_common = dict(
+        showgrid=False,
+        gridcolor=colors["gray91"],
+        linecolor=colors["gray14"],
+        ticks="outside",
+        showline=True,
+    )
+    # semi-transparent black and no outline
+    shape_defaults = dict(fillcolor="black", line={"width": 0}, opacity=0.3)
+
+    # Remove arrow head and make line thinner
+    annotation_defaults = {"arrowhead": 0, "arrowwidth": 1}
+
+    template = initialize_template(
+        paper_clr="white",
+        font_clr=colors["gray14"],
+        panel_background_clr="white",
+        panel_grid_clr="white",
+        axis_ticks_clr=colors["gray14"],
+        zerolinecolor_clr=colors["gray14"],
+        table_cell_clr=colors["gray93"],
+        table_header_clr=colors["gray85"],
+        table_line_clr="white",
+        colorway=px.colors.qualitative.D3,
+        colorbar_common=colorbar_common,
+        colorscale=px.colors.sequential.Viridis,
+        colorscale_diverging=px.colors.diverging.RdBu,
+        axis_common=axis_common,
+        annotation_defaults=annotation_defaults,
+        shape_defaults=shape_defaults,
+    )
+
+    # Left align title
+    template.layout.title.x = 0.05
+
+    # Increase grid width for 3d plots
+    opts = dict(gridwidth=2, gridcolor=plotly_clrs["gray91"], zeroline=False)
+    template.layout.scene.xaxis.update(opts)
+    template.layout.scene.yaxis.update(opts)
+    template.layout.scene.zaxis.update(opts)
+
+    # Darken ternary
+    opts = dict(linecolor=plotly_clrs["gray14"], gridcolor=plotly_clrs["gray91"])
+    template.layout.ternary.aaxis.update(opts)
+    template.layout.ternary.baxis.update(opts)
+    template.layout.ternary.caxis.update(opts)
+
+    # Remove lines through the origin
+    template.layout.xaxis.update(zeroline=False)
+    template.layout.yaxis.update(zeroline=False)
+
+    # Separate histogram bins wit ha white line
+    opts = {"marker": {"line": {"width": 0.6, "color": "white"}}}
+    template.data.histogram = [opts]
+
+    # Mapbox light style
+    template.layout.mapbox.style = "light"
+
+    # Set table header font color to white
+    return template
+
+
+builders["simple_white"] = simple_white
+
+
 def seaborn():
     # Define colors
     # -------------


Test patch: