Miskatonic University Press

David Partridge photograph

art listening.to.art

This summer I checked on eBay to see if anything by artist David Partridge was for sale. I was surprised to see a photograph from the Universal Pictorial Press and Agency (an independent news photograph agency) for sale from a vendor in Iceland (!) who I guess had bought (some of?) the Daily Telegraph photo archive. It was taken in September 1965, just before he turned 46.

Photograph of David Partridge
Photograph of David Partridge

Here’s the back, which was stamped a few times. It looks like the Daily Telegraph used the photo in a story in June 1971. I don’t have access to digitized archives from back then, but I’ll see if I can find someone who does.

Reverse side, stamped by photo agency
Reverse side, stamped by photo agency

Today’s new issue of Listening to Art is 07.11, Mr. Partridge’s Small Valleys, a naillie from 2001.

Charting date ranges in R


I wanted to turn a table of date ranges into a chart, and I figured out a way to do it that seems worth noting in case it’s of use. I’m doing this with R in Org mode, but the only Org-specific thing is how the data is ingested—it could just as easily come from as CSV file or a spreadsheet.

Let’s say in Org I have a table of date ranges associated with a name. The date could represent when someone did something, or was somewhere, or when a type of event happened, whatever. The way I have it set up, the date ranges are MMM DD–MMM DD, separated with an en dash. (It may seem silly to use an en dash, but they are correct for connecting date ranges, so it’s not silly, it’s pedantic.) We’ll turn that into something more general.

#+NAME: example_table
| name | range         | year |
| A    | Jul 16–Aug 18 | 2020 |
| B    | Jul 16–Aug 01 | 2020 |
| B    | Aug 13–Aug 22 | 2020 |
| B    | Sep 03–Sep 07 | 2020 |
| A    | Sep 01–Oct 02 | 2020 |
| C    | Aug 04–Aug 12 | 2020 |
| C    | Aug 19–Oct 02 | 2020 |
| A    | Jun 28–Jul 16 | 2019 |
| B    | Jun 28–Jul 03 | 2019 |
| A    | Jul 10–Jul 16 | 2019 |
| B    | Aug 08–Aug 30 | 2019 |
| C    | Aug 22–Aug 28 | 2019 |
| C    | Sep 01–Oct 12 | 2019 |
| A    | Aug 08–Aug 13 | 2019 |

Now I start the R source blocks. First is always the setup, which I’ll only run once per session.

#+begin_src R :session R:days :results silent

The next block has a pipeline that reads the data from the table (thank you, Org) and splits the date ranges on the en dash so it can make two new columns with properly formatted dates for the start and end. The separate command comes from tidyr. If the original data looked like this, it wouldn’t be necessary to munge it, but I’m dealing with what I have.

#+begin_src R :session R:days :results value :var raw_example_dates=example_table :colnames yes
example_dates <- raw_example_dates %>%
    separate(col = "range", sep = "–", c("start", "end")) %>%
    mutate(start = paste0(start, ", ", year), end = paste0(end, ", ", year)) %>%
    mutate(start = mdy(start), end = mdy(end)) %>%
    mutate(name = as.factor(name)) %>%
    select(-year) %>%

| name |      start |        end |
| A    | 2020-07-16 | 2020-08-18 |
| B    | 2020-07-16 | 2020-08-01 |
| B    | 2020-08-13 | 2020-08-22 |
| B    | 2020-09-03 | 2020-09-07 |
| A    | 2020-09-01 | 2020-10-02 |
| C    | 2020-08-04 | 2020-08-12 |

Now I have a data frame (actually a tibble) with start and end dates for each thing. If your data is kept in a more orderly way, you could start here.

Next I need to build a tibble that has one row for each day for each thing. The next block has this and some more stuff.

First, I set up tmp_dates, a tibble that has a throwaway row that is just there to set up the column types. There’s probably a better way to do this, but I didn’t see how.

Next, I use pmap_dfr from purrr to iterate over the rows in the data. What I’m doing I copied from Map over each row of a dataframe in R with purrr by Angelo Zehr, because I’m new to purrr, but thanks to Zehr’s example I got the hang of it.. Row by row (where each row becomes a one-row tibble called current), I build a new multi-row tibble (tmp_table) where one column is the name (repeated on each row) and the other is a sequence of dates, made using seq from the start date to end date. The new tibble has one row for each date in the date range. It adds this table (with bind_rows) to the tmp_dates table it’s building along the way, which ends up being the return value of the function.

After that, I throw away the row I don’t need any more, and I do a date trick I use when I’m comparing dates across years and want everything to line up year to year: I make a column for the year that will be used for identification, and then adjust all the years so they are in 2020. For example, “2019-08-01” is in year 2019 but is changed to “2020-08-01” so it’s simple to compare 2019 and 2020 to each other.

Finally, I find the minimum and maximum dates so I can set limits on what the charts show. My data is focused on spring–fall, so I don’t want to waste space showing January or December.

#+begin_src R :session R:stony :colnames yes
tmp_dates <- tibble(name = "X", date = as.Date("2020-01-01")) ## Set up so column types are set.
eg_dates <- example_dates %>%
    pmap_dfr(function(...) {
        current = tibble (...)
        dates <- seq(current$start, current$end - days(1), by = "day")
        tmp_table <- tibble(name = current$name, date = dates)
        details <- bind_rows(tmp_dates, tmp_table)
eg_dates <- eg_dates %>%
    filter(! name == "X") %>%
    mutate(year = year(date), date = date - years(year - 2020))
min_x_date <- min(eg_dates$date)
max_x_date <- max(eg_dates$date)

| name |       date | year |
| A    | 2020-07-16 | 2020 |
| A    | 2020-07-17 | 2020 |
| A    | 2020-07-18 | 2020 |
| A    | 2020-07-19 | 2020 |
| A    | 2020-07-20 | 2020 |
| A    | 2020-07-21 | 2020 |

Now I can make a chart. I’ll switch to syntax-highlighted R here.

ggplot(eg_dates, aes(x = date, y = as.character(year), fill = as.factor(year))) +
    geom_tile(show.legend = FALSE, aes(width = 1, height = 0.8)) +
    xlim(min_x_date, max_x_date) +
    facet_grid(name ~ .) +
    labs(title = "Days (by name)",
         x = "", y = "") +
      scale_colour_brewer(palette = "Dark2")
Days by name
Days by name

geom_tile makes a nice viz, but geom_point could also be used, though you’d need to change fill to colour. With three names and two years using colours may not be necessary, but with more data, it helps. I set the y-axis to be as.character(year) so R doesn’t show 2019, 2019.25, 2019.5, 2019.75, 2020.

Finally, here’s a chart groups by years, comparing names within each year. Left alone the years ended up with 2019 at the top, which I didn’t like (in other charts it goes low up to high, so 2020 is at the top) so I had to reorder (by reversing) the factors. As always, there’s probably a better way to do this, but it works.

## Here to get 2020 at the top we need to fiddle with factors.
reordered_eg_dates <- eg_dates %>% mutate(year = as.factor(year))
reordered_eg_dates$year <- factor(reordered_eg_dates$year, levels = rev(levels(reordered_eg_dates$year)))

ggplot(reordered_eg_dates, aes(x = date, y = name, fill = name)) +
    geom_tile(show.legend = FALSE, aes(height = 0.8)) +
    xlim(min_x_date, max_x_date) +
    facet_grid(year ~ .) +
    labs(title = "Days (by year)",
         x = "", y = "") +
    scale_colour_brewer(palette = "Dark2")
Days by year
Days by year

Those are just the visualizations I wanted.

Dr. Canadiana


Speaking of podcasts, my friend and collaborator Ashley Williamson (with whom I did Theatre Science) is teaching an intro to Canadian theatre history at the University of Toronto, Mississauga this term. It’s all online. As a way to get background information to her students outside of class time, so there’s more time in class (done over Zoom or something similar) for discussion and questions and problems, she’s doing a podcast: Dr. Canadiana.

It’s made for her students, but will be of interest to anyone who wants to learn more about the subject. The episodes are about twenty minutes, and there will be some special mini-episodes digging into detailed topics. Each one is well researched and covers a lot of ground but in a lively and engaging way—this is definitely not an academic reading a paper in a dull drone.

25 Minutes of Silence

john.cage podcasts

Back in early 2017 I discovered Joey Clift’s excellent podcast series 25 Minutes of Silence. In May I appeared in an episode! Then the series stopped (I hope not because of me) and all the episodes went away. I just discovered Clift uploaded them all to the Internet Archive! Highly recommended. The episodes with Laura Kuhn and Jerry M. Linenger are especially good.

Listening to Art ad


I ran an ad for Listening to Art in the September 2020 issue of one of my favourite magazines: The Wire.

The quarter-page advertisement
The quarter-page advertisement

I got the idea while reading Duchamp Is My Lawyer: The Polemics, Pragmatics, and Poetics of UbuWeb by Kenneth Goldsmith, who runs UbuWeb. He mentions the advertisement that Lynda Benglis ran in Artforum in November 1974. She ran it so she could have control of the image, and get something into the magazine that they didn’t want to run as editorial content. What I’m doing is utterly different, but the idea of running an advertisement got me thinking.

The advertising rates at The Wire say a “sixteenth page” (imagine dividing the page up into a four-by-four grid—this is one rectangle, 51.25 mm wide by 62 mm high) is £75 for full colour. I did one up and sent it in and things got underway. Before it went to print the advertising contact said there was a chance they could bump it up to a quarter-page ad at no extra charge! To my great fortune, that’s how it ended up.

The entire page
The entire page

Donna Summer and the Dance

anthony.powell music

I was surprised to hear Anthony Powell named as an inspiration for Donna Summer’s I Remember Yesterday album on the new episode of the BBC Radio Four show Great Lives: Jessie Ware on Donna Summer.

Pete Bellotte (who produced the album with Giorgio Moroder) is the expert witness, and says:

Donna’s next record was called Love Trilogy, and this was because I’d been reading Mervyn Peake’s Gormenghast Trilogy. The third album, I’d been reading Alexandria Quartet by Lawrence Durrell, and we turned that into Four Seasons of Love. Then the next album, I’d been reading Dance to the Music of Time by Anthony Powell, which is twelve volumes, and it gave me the idea of taking songs from the fifties, going through Tamla, funk, coming up to today, and then ending on a futuristic song, and that was how “I Feel Love” came about.

Terry Pratchett on shades of grey


From Carpe Jugulum by Terry Pratchett, in one of the conversations between the witch Granny Weatherwax and Omnian missionary Mightily-Praiseworthy-Are-Ye-Who-Exalteth-Om Oats.

“And that’s what your holy men discuss, is it?”

“Not usually. There is a very interesting debate raging at the moment about the nature of sin, for example.”

“And what do they think? Against it, are they?”

“It’s not as simple as that. It’s not a black and white issue. There are so many shades of grey.”



“There’s no greys, only white that’s got grubby. I’m surprised you don’t know that. And sin, young man, is when you treat people as things. Including yourself. That’s what sin is.”

“It’s a lot more complicated than that—”

“No. It ain’t. When people say things are a lot more complicated than that, they means they’re getting worried that they won’t like the truth. People as things, that’s where it starts.”

“Oh, I’m sure there are worse crimes—”

“But they starts with thinking about people as things.”

This was the fourteenth Discworld book I reread this year. It’s one of the best, and that’s saying a lot.

See also Denton on Discworld, a short thing I wrote at work in a series on pandemic reading.

Tuesday, March 178th, 2020


Jamie Zawinski does it in Perl: The date is now Tuesday, March 178th, 2020. Here it is in R:

$ Rscript -e 'march_date <- as.integer(Sys.Date() - as.Date("2020-02-29")); sub("XX", march_date, format(Sys.time(), "%Y-03-XX %T"))'
[1] "2020-03-178 18:50:47"

Firefox and Emacs again

emacs r

There was a new version (27.1) of Emacs earlier this month, and today Firefox version 80 is out. This reminded me of When will Firefox overtake Emacs? (from 2012) and Firefox overtook Emacs (2014).

I updated the release history data a CSV file (the ugly date format is because it’s easiest to copy and paste from the Firefox version history article on Wikipedia; the Emacs release history has better dates) and if you have R installed (and the tidyverse) then you can generate the chart with this pipeline:

## install.packages("tidyverse")

read_csv("https://www.miskatonic.org/files/se-program-versions-3.csv") %>%
  mutate(date = as.Date(Date, format = "%B %d, %Y")) %>%
  ggplot(aes(x = date, y = Version, colour = Program)) +
    geom_point() +
    geom_step() +
    labs(title = "Emacs and Firefox release history",
     caption = "William Denton (CC BY)",
     x = "",
     colour = "")
Chart of Emacs and Firefox version number history
Chart of Emacs and Firefox version number history

Firefox is the best browser still, but you can run Firefox inside Emacs. It may do releases more slowly, but Emacs will always win this contest. Or any contest.



I got an email on 20 August from my internet service provider, TekSavvy:

In August 2019 the Canadian Radio-television and Telecommunications Commission (CRTC) announced final rates that companies like TekSavvy are charged by the large telecom carriers. In some cases, those new rates were a reduction of more than 43%. TekSavvy took steps to pass on those savings on by reducing rates for the vast majority of our customers. We saw it as simply the right thing to do.

However, the large carriers petitioned Federal Cabinet to overturn the CRTC’s decision and impose higher rates. In their recent August 15, 2020 statement, the Federal Cabinet effectively directed the CRTC to increase these wholesale rates. Ultimately, in announcing its verdict on the petitions, Cabinet caved to pressure from the large carriers, who threatened to hold back investments in rural Canada unless they were protected from competition. The decision is a reversal from Cabinet’s previous direction that the CRTC place affordability, competition and consumer interests at the forefront.

After 5 years of cost uncertainty, inflated interim rates, and anti-competitive behaviour by the large carriers, TekSavvy is left with no choice but to interpret this announcement as an expectation from the government that retail prices should be raised, specifically to protect Incumbent investments. We are therefore making a difficult decision in order to continue providing you with the service you have come to expect.

We’re writing to notify you about changes to the pricing of the services that you have with TekSavvy. Starting with your first billing cycle with an effective date of service on or after October 1, 2020 there will be a change to your current package with us for OID2xxxxx. Your current package 150 Mbps with Unlimited GB of usage at a monthly cost of $67.95 will be invoiced at $77.95. Your package speed and monthly usage will not change.

They’d posted about it on 17 August: Cabinet decision means higher prices, less competition for Internet services: TekSavvy. The press release from the government is here: Response by the Government of Canada to petitions concerning CRTC wholesale Internet rates.

The government made the wrong decision. The prices charged by the big phone companies for telephone and internet access are way too high. The rates they charge to smaller companies like TekSavvy for access to their networks need to be lower.

This decision will make internet access worse for Canadians. This year, we all need reliable internet access more than ever. That will just be more true year after year.

List of all blog posts