cmap-repos / cmapplot Goto Github PK
View Code? Open in Web Editor NEWSet of templates and themes to apply CMAP graphics standards to R products.
Home Page: https://cmap-repos.github.io/cmapplot/
License: Other
Set of templates and themes to apply CMAP graphics standards to R products.
Home Page: https://cmap-repos.github.io/cmapplot/
License: Other
In time series, x labels should be integers. Also, in some situations we have published graphs where the first year is full ("2001") and those that follow are partial ('02, '03, '04, etc). We could make this an easy add (I've already found a source for the first half).
Minor change, but I think we should change the default spacing for faceted graphs (currently unit(consts$half_line, "pt")
) to some larger value, as it can be quite tight in the current defaults, particularly when the whole background is the same color (white) and there is only a small break, which can lead to overlapping axis values.
I propose that we do this after #72 is merged.
Moving this to a new issue:
Originally posted by @dlcomeaux in #8 (comment)
For fonts and sizes, use the DESIGNER GUIDELINES section of this guide.
For general layout, use a recent policy update such as this one.
Develop in R/theme_cmap.R
Timi ran into a problem today in which he needed to modify a value of cmapplot_globals
- in his case, he wanted to shrink cmapplot_globals$fsize$S
to something smaller than 11, the default. This is difficult/impossible to do from outside the the package, because (contrary to it's name!) cmapplot_globals
is not a "global" variable from the user's perspective.
We could use a simple setter function modify_globals(name, value)
that modifies a certain constant of cmapplot_globals
.
Use cases:
# if name is found in cmapplot_globals, change the value of cmapplot_globals$name and return confirmation message
modify_globals("fsize$S", 8)
#if name is not found, do nothing and return error message
modify_globals("foo", 5)
this should be easy to do with the function assign
... something like assign(paste0("cmapplot_globals$", name), value)
... although I'm not sure that $
works within functions/strings like that.
I made some changes in a branch to the theme. Not sure how to test them.
I changed the font and title placement.
I made the left margin big - per CMAP standard. However I think the margin should really be x% of chart size rather than points or cm. Wecome to thoughts.
Looks like NBER has officially placed the US in a current recession (has no close-date), which is throwing off the function. Also, they upgraded their website and changed the URL location for the excel file. Quick fix applied in #85, but should revisit and make sure is working properly. Looks like the open-ended current recession is not processing correctly.
In addition, tryCatch methods should be implemented within the function so it doesn't hard-error, which will require revisiting the code within geom_recessions()
(and presumably removing the TryCatch code implemented there)
add an argument called debug_grobs
or similar, and implement code that draws outlines around the various grobs and viewports if the argument is set to TRUE.
With texbox grobs, this is probably best done in box_gp
. In the plot, easiest is likely adding a theme element to the plot that paints a border. (this might change depending on @dlcomeaux 's legend implementation).
see e.g. Noel's ACS indicator R script and this graph.
One of the examples in finalize_plot refers to the argument title_width
. This should be updated to sidebar_width
and a quick scan of examples in other man files should be done to confirm no deprecated args or constants are used.
From @gritzenthaler:
Maps are beyond the scope of this project, but perhaps someone might have a graphical need for displaying a continuous palette in binned form? Do you think it's worth taking the time to add a "discrete" argument to the functions? (The Viridis source code is here for reference: https://github.com/sjmgarnier/viridis/blob/master/R/scales.R. I'm poking around in it now.)
Questions about label_last_point mostly pertain to implicitly automating behavior that the user is likely to need pretty much every time this function is added. Of course, this means more work now, and it may be that some of these things are not worth the effort. But here's what comes to mind:
1. Could it be programmed in such a way that defaults to taking the Y axis value as the label, rather than requiring the user to set the label attribute in top-line aes? Considering that the following two code blocks yield the same output, can geom_text_lastonly()
be set up to inherit the master aes y value as it's label value?
2. Similar question re formatting: could the formatting applied to the y axis apply to the label by default?
3. in my test plot, which involves a legend, the legend gets modified by the addition of the label. See the image below.
4. I forget where we left this off in our discussion last week - considering so much of the functionality is the same, is it worth incorporating adding a dot on the last point into the same function?
5. is it within reason to automate the expand_scale()
so it occurs within this function?
6. Add optional point_aes
and text_aes
parameters to allow separate control of label/point geom parameters.
Originally posted by @tallishmatt in #23 (comment)
For the cookbook's fourth vignette, we decided to make a list of example "fully baked" CMAP charts. These should hit each of the major categories of charts that are regularly produced in CMAP publications and analyses. @gritzenthaler @nmpeterson @matthewstern @sarahcmap - please feel free to claim one (or more) of the following, or adding your own ideas, by editing this overview.
We can also have two examples for some of these, if there are good ones - in particular, given how common line and bar charts are, those might be good to have some extra.
Sample charts
In iteration through multiple save modes, finalize_plot
will crash if one save fails. For example, if "test.pdf" already exists and is open by the user, so cannot be written to. Better behavior would be to skip that file if opening the device fails. I tried to implement tryCatch
but couldn't figure it out.
Relatedly, the function currently overwrites past outputs with the same name with no warning or confirmation. Ideally tackled at the same time as the error handling above, it would be nice to introduce a new argument such as overwrite = TRUE
, and have the function skip any existing file outputs that already exist if the argument is FALSE (the default).
Edit: the solution probably looks like this:
if(file.exists(file) & !overwrite){
# warn and skip
} else {
tryCatch{
# attempt the save
# warn and move on if erroer
}
}
@MMenninger is it possible for you to import a couple of sample datasets still? It would be great to have a few things in here that are transportation focused, so that we can make sure we test with other types of data besides for economic and demographic.
It took me longer than I want to admit to figure out how to load in and document sample data. I would be happy to sit down with you and walk you through what I did. In hindsight it wasn't complicated...just not obvious how to do it right.
Figure out the easiest way to assign the midpoint of divergent palettes
lead on this here
ggplot(filter(grp_over_time, category == "Services"), aes(x = year, y = realgrp, color = cluster)) +
geom_recessions(text_nudge_x = 0.1, text_nudge_y = 1) +
theme_cmap(hline = 0,
axislines = "x",
legend.max.columns = 3) +
geom_line() +
scale_x_continuous("Year", breaks = 2007:2017) +
geom_text_lastonly(aes(label = realgrp), add_points = TRUE)
For our convenience, I set up a "GitHub Action" that rebuilds the pkgdown site every time a commit is pushed to master (including PR merges). This action was developed by the r-lib team (who developed pkgdown, devtools, usethis, roxygen2, etc.), and was set up to run the site-building functions in a virtual macOS environment operated by GitHub. (From what I can tell, a new environment is created from scratch each time the action is run, and deleted upon completion.)
The obvious issue with this, for our purposes, is that the graphics generated for our website use the non-Windows font settings (i.e. Arial-only). I think it would be possible to reconfigure the action to use a Windows environment instead (which the R-CMD-check action already does), if we want the graphics to use Calibri instead of Arial.
If we want the graphics to use Whitney (once we have access to it), I think the only option will be to disable the pkgdown action and rebuild the site manually from our own PCs using pkgdown::deploy_to_branch
each time we update master. This seems like a pain in the ass, and is likely to be forgotten for minor commits. Is the trade-off worth it? What are others' thoughts on this?
Finalize fails for me due to a lack of unit object sometimes--it looks like this happens specifically when passing a non-theme-cmap() plot to finalize(). While this is an unlikely occurrence, it's not preferable and it would be nice to allow the user to do this if they wanted. It would be good to explore this and root out the problem if possible.
My initial guesses is this has something to do with the various theme modifications that work within finalize, and/or the legend extraction process.
svg exports do not display correctly in Illustrator. However, they look fine in browsers. This is not a major issue, but solving it would be nice.
@sarahcmap reports that plots exported with ggsave()
do display correctly in Illustrator.
I wanted to apply the built-in CMAP continuous palette to produce a continuous gradient fill aesthetic in a stacked bar chart. When I apply cmap_fill_continuous(palette = "seq_blues")
to a stacked bar chart, I get the following error: "Error: Discrete value supplied to continuous scale". If I switch to cmap_color_continuous(palette = "seq_red_purple")
, the code is ignored and the default ggplot colors are used.
I ended up having to use the ggplot color brewer, which worked. The example output I seek is attached.
scale_fill_brewer(palette = "Blues")
I tried installing the package to use it on a graph I'm making, and it appears that the font issues we thought we'd solved are not solved. When I attempt to create a graph using theme_cmap
it gives the following (and annoyingly familiar) error
message:
Warning messages:
1: In grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, :
font family not found in Windows font database
2: In grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, :
font family not found in Windows font database
3: In grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, :
font family not found in Windows font database
4: In grid.Call(C_textBounds, as.graphicsAnnot(x$label), x$x, x$y, :
font family not found in Windows font database
As a result, it is exporting text in Arial, and not Calibri. The issue persists even after running finalize
.
I'm not really sure how best to proceed on fixing this, as I really thought we had. But flagging for others to test if they get the same issue. In either case, we need to do some investigating.
geom_text_lastonly
?)theme_cmap
is applied.export WEB, POWERPOINT, and REPORT versions of graphics as per the DESIGNER GUIDELINES section of this guide
Presumably based on bbplot::finalise_plot
This is a weird bug, but I've noticed that when I try to add spacing between panels, it doesn't work. What's weirder is that it also adds the numeric value of the spacing you add below the plot.
For example, this yields the following chart:
chart2 <- project_type_spending_ratio %>%
filter(DisplayGroup == "Neither" | DisplayGroup == "EDA and/or DA") %>%
filter(!(PROJECT.TYPE %in% null_types)) %>%
filter(ratio_type %in% c("area_ratio","pop_ratio")) %>%
mutate(ratio_type = case_when(
ratio_type == "area_ratio" ~ "2. Per acre",
ratio_type == "pop_ratio" ~ "1. Per capita"
)) %>%
ggplot(aes(x = value, y = reorder(PROJECT.TYPE,desc(PROJECT.TYPE)))) +
geom_bar(aes(fill = DisplayGroup), stat = "identity", position = position_dodge(width = .55), width = .5) +
facet_grid(~ratio_type,scales = "free") +
theme_cmap(gridlines = "hv",theme(panel.spacing.x = unit(5,"lines"))) +
scale_x_continuous(labels = scales::label_dollar()) +
cmap_fill_discrete(palette = "governance")
I can try to look into this, but does anyone have any initial ideas? @matthewstern @nmpeterson ? Maybe this will get solved by having a complete theme? (We can hope)
I spent a little bit of time working on a potential logo for the package, putting a CMAP twist on the tidyverse hexagon theme (they're seriously obsessed). I'm envisioning this being displayed both on the readme (i.e. GitHub project main page) like on ggplot2, as well as the navigation bar for the pkgdown site.
Thoughts?
Use Calibri if possible.
Establish a digital book that helps new learn CMAPplot and help returning users implement it.
It's probably worth starting with reviewing the documentation for bbplot, and then implementing a framework for documentation development (pkg-down or bookdown?).
A few months ago, I had started to outline what should go in this packages readme and what should go in rmarkdown. I added a wiki file for the outline here, in the hopes we can develop it collaboratively.
build a range of palettes including race/eth, Chi region and peers, and various sub-palettes and color scales for discrete and continuous data. All based on the master CMAP color palette.
Feel free to add/change this list based on your notes:
Fonts @nmpeterson
Finalize @dlcomeaux
theme_cmap (@sarahcmap would you be willing to work on this?)
axis.line.x
and axis.line.y
in optional constructions that look very similar to how gridlines are currently specified.highlight last @nmpeterson
recessions @matthewstern
colors @gritzenthaler
I've come across some plots where it would be helpful to have control over the formatting of the labels and text in the cmap_fill_continuous
(and other cmap scales). The vanilla versions of these functions allow such modifications (see here) but I believe our current configuration does not.
Right now, the cmap_fill_race
and cmap_color_race
will only work if your race/ethnicity designations are in lower case. I propose that we also enable it to work in the case when they are the same words but in different cases, to make it easier to generate production-ready graphics. I can look into this, I don't imagine it will be terribly complicated.
We should discuss whether it makes sense to upgrade font handling to use the new package systemfonts and new raster devices from the ragg package.
Resources:
While systemfonts should be able to handle fonts natively to some degree, it looks like a good way to guarantee font handling is to check for the font by filtering the df returned by system_fonts()
, and if found use register_font()
. We could do this with all three fonts we use, e.g.:
library(systemfonts)
register_font("Whitney Medium", "C:\\Windows\\Fonts\\Whitney-Medium-Adv.otf")
registry_fonts()
> path index family style weight italic features
> 1 C:\\Windows\\Fonts\\Whitney-Medium-Adv.otf 0 Whitney Medium Regular normal FALSE NULL
> 2 C:\\Windows\\Fonts\\Whitney-Medium-Adv.otf 0 Whitney Medium Bold bold FALSE NULL
> 3 C:\\Windows\\Fonts\\Whitney-Medium-Adv.otf 0 Whitney Medium Italic normal TRUE NULL
> 4 C:\\Windows\\Fonts\\Whitney-Medium-Adv.otf 0 Whitney Medium Bold Italic bold TRUE NULL
... except use the path from the df returned by system_fonts()
.
However, devices that don't communicate with systemfonts will not recognize these fonts. So, we'd need to address that across the board:
I just upgraded RStudio (with IT help) and can confirm that after "registering" Whitney Medium as above...
ggplot() +
geom_text(
aes(x = 0, y = 1, label = "the default is Arial"),
size = 6
) +
geom_text(
aes(x = 0, y = 0, label = "This is Whitney Medium"),
family = "Whitney Medium",
size = 6
) +
expand_limits(y = c(-1, 2)) + theme_void()
Note that the use of ragg
as the default in Rstudio can be evaluated and set by code, so we could issue a package startup message or warning if ragg is not used, and/or actually have the package force the change (which we probably don't want to do).
> getOption("RStudioGD.backend")
[1] "default"
> options(RStudioGD.backend = "ragg")
> getOption("RStudioGD.backend")
[1] "ragg"
This seems likely to fix #116, as pkgdown now uses ragg devices by default.
@nmpeterson per your request to document the sample datasets I added, I attempted to follow the instructions you sent here, which led me to chapter 8 of the same book and to the basics of Roxygen. However, I am lost and could use your help.
I am working in the 'adtl-sample-data' branch. I have code in the file data.R that should generate a man file, but when I attempt to build the man files by running devtools::document()
from the console, I get an error that has to do with sample_graphics.R:
Error in theme_cmap() (from sample_graphics.R#8) : could not find function "theme_cmap"
Would appreciate your troubleshooting help so that we can figure out how to use roxygen for all documentation, as that seems to be a common method/best practice for documentation.
Thank you!
library(cmapplot)
> economy_basic
variable year sector value
1 Jobs 2001 local 2175402
2 Jobs 2001 tradedgoods 440908
3 Jobs 2001 tradedservices 1153064
4 Jobs 2017 local 2482547
5 Jobs 2017 tradedgoods 312112
6 Jobs 2017 tradedservices 1137597
7 Real Earnings 2001 local 109373872297
8 Real Earnings 2001 tradedgoods 32443025020
9 Real Earnings 2001 tradedservices 98962528774
10 Real Earnings 2017 local 127029954775
11 Real Earnings 2017 tradedgoods 28297549664
12 Real Earnings 2017 tradedservices 111886397025
13 Establishments 2001 local 121282
14 Establishments 2001 tradedgoods 8159
15 Establishments 2001 tradedservices 53911
16 Establishments 2017 local 146391
17 Establishments 2017 tradedgoods 8550
18 Establishments 2017 tradedservices 59761
ggplot(cluster_jobchange, aes(x = reorder(name, jobchange), y = jobchange, fill = category)) +
geom_col() +
coord_flip() +
cmapplot::theme_cmap()
Error in ggplot(cluster_jobchange, aes(x = reorder(name, jobchange), y = jobchange, :
object 'cluster_jobchange' not found
ggplot(cars) +
a grouped and stacked bar chart (via
interaction()
)ggplot(economy_basic, aes(x = interaction(year, variable), y = value, fill = sector)) +
Update font specification to check current platform and do something different if non-Windows.
In this ggplot, the text for geom_text_lastonly
is selected automatically/by default in some way that I am not familiar with:
ggplot(data = df,
mapping = aes(x = year, y = ridership, color = system)) +
geom_recessions(ymin = 0) +
geom_line(size = 1) +
theme_cmap(ylab = "Annual Ridership (Millions)") +
geom_text_lastonly(add_points = TRUE,
nudge_x = 0.5) +
coord_cartesian(clip = "off")
However, if the user wants to specify/customize the text, I believe label
must be specified in aes()
, such as this:
ggplot(data = df,
mapping = aes(x = year, y = ridership, color = system, label = round(ridership, digits = 0))) +
geom_recessions(ymin = 0) +
geom_line(size = 1) +
theme_cmap(ylab = "Annual Ridership (Millions)") +
geom_text_lastonly(add_points = TRUE,
nudge_x = 0.5) +
coord_cartesian(clip = "off")
This aes should be able to be specified in either the top-line ggplot (above) or in the geom (below). Interestingly, for me, the following works but throws an error message "Ignoring unknown aesthetics: label".
ggplot(data = df,
mapping = aes(x = year, y = ridership, color = system)) +
geom_recessions(ymin = 0) +
geom_line(size = 1) +
theme_cmap(ylab = "Annual Ridership (Millions)") +
geom_text_lastonly(mapping = aes(label = round(ridership, digits = 0)),
add_points = TRUE,
nudge_x = 0.5) +
coord_cartesian(clip = "off")
Why does the warning get triggered?
I think it would be nice to include a news page on the pkgdown site that automatically captures updates via the github releases tool. In my mind, every few PR merges should get a release update, and it would make sense to capture that in a changelog on the website.
This does not seem hard to do: https://pkgdown.r-lib.org/reference/build_news.html#yaml-config
Per an earlier conversation with @matthewstern in #68 I wanted to add a potential enhancement: making it easier for users to turn on tick marks. As this stands, it requires modifications to two different elements of the theme (see here), but this could be simplified for users that want to add a "default" style tick mark.
I just ran into a case where I wanted to apply a color palette to a histogram with cmap_fill_discrete()
. I also wanted to modify the legend labels, so I added scale_fill_discrete()
with the labels
parameter. These two functions conflict with each other, and only the last-specified one will be applied.
> ggplot(FACTORS_MUNI) +
+ geom_histogram(aes(x=SCORE_OVERALL_SCALED, fill=COHORT)) +
+ theme_cmap() +
+ scale_fill_discrete(labels=c("Cohort 1", "Cohort 2", "Cohort 3", "Cohort 4")) +
+ cmap_fill_discrete(palette="community")
Scale for 'fill' is already present. Adding another scale for 'fill', which will replace
the existing scale.
So with the above order, I got a plot that had the cmapplot palette applied, but not my custom labels. Switching the order yields a plot with custom labels and default ggplot colors. I tried supplying the labels
parameter to cmap_fill_discrete
, but we have not implemented that.
My current workaround is to use scale_fill_manual
, where I can specify my own colors and labels.
I propose that all of cmapplot's color scale functions get a ...
parameter that passes any extra parameters to the underlying ggplot scale functions that we're relying on.
It appears all fonts in plots on the pkgdown site are currently rendering in Arial. Noel, would you be willing to look into why this is the case, and hopefully implement a solution within #115?
As I was re-making the Census graphic, I noticed that our current default setting for the margin between axis labels and the plot is 5 big points, which is significantly larger than the similar spacing in the comms-produced graphic. Also, that value (5) is hard-coded into theme_cmap()
, which might be better served as an adjustable value in the overrides
list.
Flagging here because I think this could also benefit from adding the same functionality for y-axis labels, in cases where the labels are on the side - currently, the margin for those is not manually adjusted, and remains at the default.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.