sc.tools?sc.pl?sc.external.*?To reduce the number of arguments that are passed to plotting functions and to agrupate them by type I was considering the following example syntax:
sc.pl.umap(adata, color='clusters').scatter_outline(width=0.1)
.legend(loc='on data', outline=1)
.add_edges(color='black', width=0.1)
or
sc.pl.dotplot(adata, ['gene1', 'gene2'], groupby='clusters')
.add_dendrogram(width=0.4,color='grey')
.swap_axes()
.dot_size_legend(title='fraction', location='left')
Any comments?
(I am not sure how to implement something like this)
I love this! Question from my side would be how to best make docs for this. Might fragment the documentation too much if we're not careful with this.
With respect to documentation: each plotting function becomes a module with well described functions. An example is the styling of pandas DataFrames (https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.io.formats.style.Styler.html)
That looks really good!
I support the idea of tidying up plotting arguments. I think there are mainly two problems. 1) the high number of plotting arguments 2) lack of reusability of plotting "styles".
Chaining looks really cool and improves 1). Also, it logically partitions the plotting arguments. However, it doesn't solve 2). In other words, if we plot two figures, we'll need to copy the entire thing, and it'll be very verbose:
sc.pl.umap(adata, color='clusters').scatter_outline(width=0.1)
.legend(loc='on data', outline=1)
.add_edges(color='black', width=0.1)
sc.pl.umap(adata2, color='fluffy').scatter_outline(width=0.1)
.legend(loc='on data', outline=1)
.add_edges(color='black', width=0.1)
One thing that comes to mind for reusability is to store the result of the chain somewhere and, well, reuse it:
style = sc.pl.styles.scatter_outline(width=0.1)
.legend(loc='on data', outline=1)
.add_edges(color='black', width=0.1)
# using simple arguments, similar to https://stat.ethz.ch/R-manual/R-devel/library/nlme/html/lmeControl.html
sc.pl.umap(adata, color='clusters', style=style)
sc.pl.umap(adata2, color='fluffy', style=style)
# using context managers, similar to https://seaborn.pydata.org/tutorial/aesthetics.html#temporarily-setting-figure-style
with style:
sc.pl.umap(adata, color='clusters')
sc.pl.umap(adata2, color='fluffy')
# overriding an existing style object
with style.legend(fontsize=12):
sc.pl.umap(adata, color='clusters')
sc.pl.umap(adata2, color='fluffy')
# or use predefined styles (?)
with sc.pl.style('malte'):
sc.pl.umap(adata, color='clusters')
sc.pl.umap(adata2, color='fluffy')
WDYT?
I like the idea and I see your point, however I wonder how intuitive the concept of a style is for beginners. Also you'd have to know exactly what you are looking to plot during your analysis to set up a style for all plots for the future (e.g. do you need arrows? Will you use a marker gene dotplot?). Context managers definitely look clean (I love that I have my own ^^), but it would make things a bit more difficult for beginners to get an intuitive feel for scanpy.
@gokceneraslan indeed styling needs to be addressed and your solution seems quite interesting however, I don't know how complicated is to implement something like this.
My suggestion would be to try the chaining first at least with some functions to see how practical is this. Maybe @VolkerBergen that is revising the scatter plots can try some initial steps?