# OAtrophfig4.r - R code to produce Figure 4 of # "Effects of ocean acidification on temperate coastal marine # ecosystems and Fisheries in the northeast Pacific" # by Rowan Haigh, Debby Ianson, Carrie A. Holt, Holly E. Neate and # Andrew M. Edwards, PLOS ONE. For issues with the code please contact # Andrew Edwards, Andrew.Edwards@dfo-mpo.gc.ca # Code finalised in November 2014, under R version 3.1.0. # This R is self-contained and produces the figure, as .eps, .tiff, .png # and .pdf. Any warnings are likely due to the inclusion of Arial-font # figures and the onefile=FALSE option (but the warnings disappear on # a second run, and the Arial aspects can be deleted if required). # Data are included in the code below, with their respective sources. # Contents of file: # Setup - load required packages # Functions - one function definition # Import data - load in the two datasets, included here # Construct trophLand dataframe - 'trophLand' is the dataframe being # built here to plot the figures # Maybe keep somewhere: # For groups that haven't yet been dealt with see: # i) trophLandNoTrophic - Other.groundfish and Other - see definitions. Okay # to leave out. # ii) preikNoValue - could include jellies but trophic of 3.2 seems high. # krill is the only other one that could include, but no landed value. # Trophic levels were based on the BC shelf output from Preikshot # (2007 [PhD], pers.~comm.), and are used to structure the figure. # Giving trophic level of 7 for cultured, # may want to put them on same figure to the side. # Putting NA for now for trophic levels that we don't have. # Dave's output file BCshelfPars.txt - have commented out juveniles, which # are given similar trophic levels to adults anyway. # Using Arial font, as requested by PLOS ONE. # Based on http://www.fromthebottomoftheheap.net/2013/09/09/preparing-figures-for-plos-one-with-r/ # need to do the following once for R to find all the fonts # on computer, then the postscript() etc. code below should work (else # just edit the postscript etc. commands to not use Arial, and comment out the # loadfonts() command): # install.packages("extra.font"); library("extrafont"); font_import(); # fonts() # lists the fonts registered, I had 226. # Arial doesn't get embedded, but most machines should have it and PLOS ONE will # have it in their publication process. # *** SETUP *** rm(list=ls()) require(PBSmodelling) require(PBSmapping) # for makeGrid require(sp) # for something in PinP function require(extrafont) # for using Arial loadfonts(device="postscript", quiet=TRUE) loadfonts(device="pdf", quiet=TRUE) # *** FUNCTIONS *** # PinP function - points in a polygon adapted for a circle by Rowan Haigh, PinP = function(a=5,b=5,r=1,pdens=50, xlim=xLim, ylim=yLim) { rads=pi*(1:360)/180 x = a + r * diff(xLim) / diff(yLim) * par("pin")[2] / par("pin")[1] * cos(rads) # par("pin") is plot size y = b + r* sin(rads) z = makeGrid(x=seq(xlim[1],xlim[2],length=pdens), y=seq(ylim[1],ylim[2],length=pdens),projection=1) is.in = as.logical(point.in.polygon(z$X,z$Y,x,y)) points(z$X[is.in],z$Y[is.in],pch=20,col="red", cex=0.4) } # *** IMPORT DATA *** # Originally imported data from Dave Priekshot's output file: # preik = read.table(file="../BCshelfPars.txt", header=TRUE) # row.names(preik) = preik$Group # label rows by group # preik = preik[,-1] # Now have saved it here to save loading in a separate file; # note that we only use the Trophic field and the organism names. preikInput = "Trophic Biomass PoverB QoverB salmon.shark 4.962 0.020 0.200 1.200 pelagic.sharks 4.848 0.030 0.140 1.000 seals 4.743 0.040 0.160 15.950 odontocetae 4.718 0.036 0.030 13.100 sea.lions 4.582 0.019 0.060 12.700 misc.pred.pelagics 4.488 0.210 0.450 6.600 lingcod 4.390 0.363 0.240 2.400 birds.demer.pisciv 4.379 0.003 0.176 164.945 birds.pelag.pisciv 4.327 0.001 0.159 254.010 coho 4.290 0.250 1.100 7.700 chinook 4.210 0.390 0.740 5.000 large.squids 4.164 0.500 2.600 6.400 sockeye 4.133 0.200 1.270 8.400 P.halibut.ad. 3.983 0.175 0.300 1.000 pink 3.904 0.200 1.400 8.900 chum 3.838 0.400 1.000 7.000 dogfish 3.834 1.300 0.100 2.700 arrowtooth.ad. 3.833 0.070 0.300 2.000 P.cod.ad. 3.660 0.300 0.660 1.800 misc.small.demersals 3.601 7.000 1.577 5.256 small.squids 3.562 2.679 3.000 15.000 misc.small.pelagics 3.556 7.452 2.300 7.667 sablefish.ad. 3.553 0.400 0.200 2.200 rockfish.other 3.548 1.000 0.180 2.600 pollock.ad. 3.504 0.700 0.400 2.000 birds.zooplanktiv 3.504 0.003 0.186 247.942 mysticetae 3.443 0.155 0.020 13.370 flatfish.other 3.405 1.300 0.600 3.000 rock.sole 3.404 0.144 0.220 2.300 Pac.Ocean.perch 3.377 0.500 0.100 2.400 yellowfin.sole 3.372 0.001 0.190 2.400 rajidae./.ratfish 3.348 0.835 0.300 1.320 Pac.hake 3.334 0.930 0.500 2.400 myctophids 3.284 4.500 0.500 6.800 herring.ad. 3.278 2.000 0.650 4.400 jellies 3.208 12.500 9.600 13.000 shrimps 3.033 5.650 1.200 9.667 carn.zooplankton 3.007 25.000 7.000 20.000 crabs 2.824 3.800 1.500 3.500 echinoderms 2.752 14.800 0.300 1.200 bivalves 2.251 7.700 0.900 4.500 krill 2.125 18.000 6.000 24.800 other.benthos 2.074 43.000 4.500 15.000 herb.zooplankton 2.000 25.000 27.000 80.000 phytoplankton 1.000 22.000 130.000 0.000 macrophytes 1.000 9.000 9.000 0.000" preik = read.table(text = preikInput, header = TRUE, row.names=1) # landValues.txt is a text file of values taken from # BC Ministry of Agriculture (2012). British Columbia Seafood Industry # 2011 Year in Review. British Columbia Ministry of Agriculture, ii + 14 pp. # http://www.env.gov.bc.ca/omfd/reports/Seafood-YIR-2011.pdf # landed = read.table(file="../landValues.txt", header=TRUE) #, sep=",") # Now have saved it here to save loading in a separate file; # note that we only use the Group and Landed.value fields. # Landed value is for 2011, and in CA$million. landedInput ="Group Harvest Landed.value Chinook 1.30 9.8 Chum 5.80 10.6 Coho 1.10 4.8 Pink 9.20 8.8 Sockeye 3.00 12.2 Atlantic.cult 79.40 408.9 Pacific.cult 3.80 26.4 Herring.spawn 0.10 1.0 Herring.roe 6.60 2.2 Herring.fbait 0.70 0.6 Arrowtooth 5.00 2.0 Dogfish 1.00 0.5 Hake 55.40 16.5 Halibut 4.00 45.6 Lingcod 1.70 4.0 Pacific.Cod 1.90 3.0 Pollock 4.00 2.0 Rockfish 18.00 26.0 Sablefish 2.20 27.2 Sole 5.00 5.5 Other.groundfish 1.40 2.0 Clams 0.60 1.3 Crabs 5.00 32.5 Geoducks 1.60 41.3 Scallops 0.01 0.2 Sea.Cucumbers 1.70 6.5 Sea.urchins.red 2.50 3.2 Sea.urchins.green 0.06 0.2 Shrimp 0.50 1.0 Prawns 2.80 40.0 Other.Shellfish 0.20 0.5 Clams.cult 1.30 7.2 Oysters.cult 7.50 9.2 Scallops.oth.cult 0.60 3.2 Tuna 5.40 28.7 Sardines 20.70 3.6 Other 0.30 1.5 Other.cult 1.20 10.5" landed = read.table(text = landedInput, header = TRUE) # *** CONSTRUCT TROPHLAND DATAFRAME *** # Create data.frame trophLand, which will be gradually built up and # then used to plot the figures. Using organism groups from the landed # values data: trophLand = data.frame(row.names=landed$Group, value=landed$Landed.value, trophic=NA, OAeffect = NA) # value - landed value for 2011 in CA$million # trophic - trophic level based on Dave Preikshot's output # OAeffect - likely effect of Ocean Acidification based on our # manuscript. # First have to deal with the organism names not being the same # in the two data sets. # Categories from landed table: # Pacific.cult is chinook, coho, and sockeye # Assume wild unless says .cult (or .wild to distinguish certain species) # Herring.spawn is spawn on kelp. .fbait is food and bait # Other.gfish includes skate and flounder and 'other gfish meal and oil # that cannot be specified by species' - leaving out. # Other.shell.wild includes octopus, squid and unspecified shellfish. Renaming # "squid & octopus". # Scallops.oth.cult - cultured scallops and other (not clams or oysters) # Other.Wild includes marine plants, mackerel and unspecified finfish - leaving # out as can't give a trophic level. # Other.cult includes marine plants, freshwater trout, sablefish, # sturgeon, tiliapia, abalone, crayfish, and sea cucumbers. # Listing them in figure. # Arrowtooth is Arrowtooth Flounder. # Squid & octopus is what was Other.shell.wild (squid, octopus, # unspecified shellfish - adding note in caption. Dave just had squid). # From Dave's Ph.D. # p47: Carn.zooplankton biomass was based on miscellaneous predatory # zooplankton, amphipods and pteropods in Eastern Subarctic model of # Aydin et al. (2003). Going to rename just 'Naked Pteropods' # Herb.zooplankton - copepods and microZ from same - now splitting # into microZ and mesoZ as that's what we have in the text. # Here adding a 'Shelled Pteropods' box, with Herb. Zoo trophic level. # Here adding a 'Glass Sponges' box, requested by Debby (unknown OA effect, # trophic level maybe just below Corals). # Here adding an 'Abalone' box since endangered; no harvest (but is listed # under the cultured list), same trophic level # as Geoduck, scallops and clams. cultTroph =NA # value to assign for trophic level of cultured # so can use symbols(trophLand,...) on the whole # dataframe, and scale circles to largest # value, which is cultured Atlantic Salmon. trophLandMaxVal = max(trophLand[,"value"], na.rm=TRUE) if(row.names(trophLand[which.max(trophLand[,"value"]), ]) != "Atlantic.cult") { stop("Will have to redo scaling on farmLand figure, including the value of the most valuable species in farmLand, but not plotting it, so that scaling is the same between figures") } # Have to add some code if most valuable is not farmed. # # Add in trophic levels from Dave's output. Any that use a mean of Dave's # need to be removed from preikNoValue below (which tells us which of # Dave's groups we haven't used at all). # Did have Chinook.wild etc., now just Chinook. trophLand["Chinook", "trophic"] = preik["chinook", "Trophic"] trophLand["Chum", "trophic"] = preik["chum", "Trophic"] trophLand["Coho", "trophic"] = preik["coho", "Trophic"] # Adding a * for indirect effects in figure: row.names(trophLand)[row.names(trophLand) %in% "Pink"] = "Pink*" trophLand["Pink*", "trophic"] = preik["pink", "Trophic"] trophLand["Sockeye", "trophic"] = preik["sockeye", "Trophic"] trophLand["Atlantic.cult", "trophic"] = cultTroph trophLand["Pacific.cult", "trophic"] = cultTroph # Combined herring into one row trophLand["Herring", "value"] = trophLand["Herring.spawn", "value"] + trophLand["Herring.roe", "value"] + trophLand["Herring.fbait", "value"] trophLand = trophLand[!(row.names(trophLand) %in% c("Herring.spawn", "Herring.roe", "Herring.fbait")),] trophLand["Herring", "trophic"] = preik["herring.ad.", "Trophic"] trophLand["Arrowtooth", "trophic"] = preik["arrowtooth.ad.", "Trophic"] trophLand["Dogfish", "trophic"] = preik["dogfish", "Trophic"] trophLand["Hake", "trophic"] = preik["Pac.hake", "Trophic"] trophLand["Halibut", "trophic"] = preik["P.halibut.ad.", "Trophic"] trophLand["Lingcod", "trophic"] = preik["lingcod", "Trophic"] trophLand["Pacific Cod","value"] = trophLand["Pacific.Cod", "value"] trophLand = trophLand[- match("Pacific.Cod", row.names(trophLand)), ] # remove row with . in name # trophLand = trophLand[-(row.names(trophLand) == "Pacific.Cod"), ] trophLand["Pacific Cod", "trophic"] = preik["P.cod.ad.", "Trophic"] trophLand["Pollock", "trophic"] = preik["pollock.ad.", "Trophic"] trophLand["Rockfish", "trophic"] = mean(c(preik["Pac.Ocean.perch", "Trophic"], preik["rockfish.other", "Trophic"])) # rockfish and POP combined trophLand["Sablefish", "trophic"] = preik["sablefish.ad.", "Trophic"] trophLand["Sole", "trophic"] = mean(c(preik["flatfish.other", "Trophic"], preik["rock.sole", "Trophic"], preik["yellowfin.sole", "Trophic"])) # NA means not in Dave's. trophLand["Other.groundfish", "trophic"] = NA # landed values defn includes # skate and flounder, but only skate (rajidae) # entry in Dave's also includes ratfish. Just exclude. trophLand["Clams", "trophic"] = preik["bivalves", "Trophic"] # Using bivalve trophic for >1 organisms trophLand["Crabs", "trophic"] = preik["crabs", "Trophic"] row.names(trophLand)[row.names(trophLand) %in% "Geoducks"] = "Geoduck" trophLand["Geoduck", "trophic"] = preik["bivalves", "Trophic"] trophLand["Scallops", "trophic"] = preik["bivalves", "Trophic"] trophLand["Abalone", "trophic"] = preik["bivalves", "Trophic"] # (even though they're not bivalves) trophLand["Abalone", "value"] = NA trophLand["Sea Cucumbers","value"] = trophLand["Sea.Cucumbers", "value"] trophLand = trophLand[- match("Sea.Cucumbers", row.names(trophLand)), ] # remove row with . in name trophLand["Sea Cucumbers", "trophic"] = preik["echinoderms", "Trophic"] # Using echino trophic for >1 organisms # Combine red and green urchins: trophLand["Sea Urchins", "value"] = trophLand["Sea.urchins.red", "value"] + trophLand["Sea.urchins.green", "value"] trophLand = trophLand[!(row.names(trophLand) %in% c("Sea.urchins.red", "Sea.urchins.green")),] trophLand["Sea Urchins", "trophic"] = preik["echinoderms", "Trophic"] # Rowan requested Other Echinoderms. See text/caption for what they include. trophLand["Other Echinoderms", "value"] = NA trophLand["Other Echinoderms", "trophic"] = preik["echinoderms", "Trophic"] - 0.2 # Shifting down slightly to fit trophLand["Shrimp", "trophic"] = preik["shrimps", "Trophic"] trophLand["Prawns", "trophic"] = preik["shrimps", "Trophic"] # Other.shell.wild (now "Other Shellfish") includes octopus, # squid and unspecified shellfish. So re-name as Squid & Octopus # Dave just had squids, so use them, and drop the wild (and for scallops, clams) trophLand["Squid & Octopus", "value"] = trophLand["Other.Shellfish", "value"] trophLand["Squid & Octopus", "trophic"] = mean(c(preik["small.squids", "Trophic"], preik["large.squids", "Trophic"])) trophLand = trophLand[- match("Other.Shellfish", row.names(trophLand)), ] trophLand["Clams.cult", "trophic"] = cultTroph trophLand["Oysters.cult", "trophic"] = cultTroph trophLand["Scallops.oth.cult", "trophic"] = cultTroph trophLand["Tuna", "trophic"] = NA # preik["", "Trophic"] trophLand["Sardines", "trophic"] = NA # preik["", "Trophic"] # Other includes marine plants, mackerel and unspecified finfish # Can't really give a trophic level for, or effect of OA, so remove. trophLand["Other", "trophic"] = NA # preik["", "Trophic"] # Other.cult includes marine plants, freshwater trout, sablefish, # sturgeon, tiliapia, abalone, crayfish, and sea cucumbers # Can't really give a trophic level for, or effect of OA, so remove. trophLand["Other.cult", "trophic"] = NA #preik["", "Trophic"] # Now to take some from Dave's for which we don't have landed values (set to NA) # See below for data.frames of what hasn't been used from each data set. # trophLand["Toothed Whales", "trophic"] = 4.88 # was = preik["odontocetae", "Trophic"] = [4.718], but moving up # a little to be above seals (that they prey on) trophLand["Baleen Whales", "trophic"] = preik["mysticetae", "Trophic"] trophLand["Sharks", "trophic"] = mean(c(preik["salmon.shark", "Trophic"], preik["pelagic.sharks", "Trophic"])) trophLand["Seals", "trophic"] = preik["seals", "Trophic"] trophLand["Sea Lions", "trophic"] = preik["sea.lions", "Trophic"] trophLand["Birds", "trophic"] = mean(c(preik["birds.demer.pisciv", "Trophic"], preik["birds.pelag.pisciv", "Trophic"])) trophLand["Lanternfish", "trophic"] = preik["myctophids", "Trophic"] trophLand["Naked Pteropods*", "trophic"] = preik["carn.zooplankton", "Trophic"] # Pteropods = naked Pterpods, who feed almost # exclusively on shelled Pteropods. Adding # * to indicate this is an indirect effect. trophLand["Microzooplankton", "trophic"] = preik["herb.zooplankton", "Trophic"] trophLand["Mesozooplankton", "trophic"] = preik["herb.zooplankton", "Trophic"] # Adding this group here: trophLand["Shelled Pteropods", "trophic"] = preik["herb.zooplankton", "Trophic"] # Adding here per Rowan's request: trophLand["Euphausiids", "trophic"] = preik["bivalves", "Trophic"] # same as # scallops etc., above zoopl. since they # eat zoopl. Rowan has a paper. trophLand["Euphausiids", "value"] = 0.22 # 2011 landed value from # Euphausiid DFO IFMP (2013-2017), Table 1. trophLand["Phytoplankton", "trophic"] = preik["phytoplankton", "Trophic"] trophLand["Macroalgae", "trophic"] = preik["macrophytes", "Trophic"] # Note, # naming them macroalage here (Carrie) # These aren't in Dave's but we have landed values for. Do values # (based on quick chat with Ian Perry): trophLand["Sardines", "trophic"] = trophLand["Herring", "trophic"] trophLand["Tuna", "trophic"] = trophLand["Chinook", "trophic"] + 0.1 # And Jessica Finney agreed 2.5 is okay for corals: trophLand["Corals", "trophic"] = 2.5 trophLand["Corals", "value"] = NA # Adding Glass Sponges trophLand["Glass Sponges", "trophic"] = trophLand["Sea Cucumbers", "trophic"] # Sally Leys suggested. trophLand["Glass Sponges", "value"] = NA # Adding Seagrasses trophLand["Seagrasses", "trophic"] = trophLand["Macroalgae", "trophic"] # Could do Other.groundfish (Skate, Flounder), but not worrying: # trophLand["Other.groundfish", "trophic"] = trophLand["Rockfish", "trophic"] # So what haven't we used from Dave's? There are only two trophic # levels that are duplicated, so we can use trophic levs with those in trophLand # to tease out which of Dave's groups haven't been used yet. # Two duplicates are 3.504 (pollock.ad and birds.zooplanktiv) # and 1.000 (phytoplankton and macrophytes) # **Note that sometimes mean trophic level has been used, so that won't # get caught here - can fix manually. if(length(preik$Trophic) - length(unique(preik$Trophic)) != 2) stop("Data changed -- different number of unique trophic levels") trophLand = trophLand[!(row.names(trophLand) %in% c("Sea.urchins.red", "Sea.urchins.green")),] preikNoValue = preik[!(preik$Trophic %in% trophLand$trophic), ] # Taking out the ones that have been used above in mean trophic calculations: preikNoValue = preikNoValue[!(row.names(preikNoValue) %in% c("Pac.Ocean.perch", "rockfish.other", "flatfish.other", "rock.sole", "small.squids", "large.squids", "salmon.shark", "pelagic.sharks", "birds.demer.pisciv", "birds.pelag.pisciv")),] # Setting xval for each row, being the x value to plot the circle/square # at. Doesn't mean anything real, just choose to construct the figure. # Could do individual values as a vector, but seems easier to make # future changes if do each one separately. trophLand$xval = 1:dim(trophLand)[1] # to give them all values # Adding values here. Commenting out if trophic==NA (so not on figure yet) trophLand["Chinook", "xval"] = 7.9 trophLand["Chum", "xval"] = 10.5 trophLand["Coho", "xval"] = 9.6 trophLand["Pink*", "xval"] = 9.2 trophLand["Sockeye", "xval"] = 10.9 # trophLand["Atlantic.cult", "xval"] = NA # trophLand["Pacific.cult", "xval"] = NA trophLand["Herring", "xval"] = 9.5 trophLand["Arrowtooth", "xval"] = 3.6 trophLand["Dogfish", "xval"] = 1.7 trophLand["Hake", "xval"] = 3 trophLand["Halibut", "xval"] = 0.5 trophLand["Lingcod", "xval"] = 0 trophLand["Pacific Cod", "xval"] = 5 trophLand["Pollock", "xval"] = 3.7 trophLand["Rockfish", "xval"] = 7 trophLand["Sablefish", "xval"] = 1.2 trophLand["Sole", "xval"] = -0.1 # trophLand["Other.groundfish", "xval"] = trophLand["Clams", "xval"] = 3.0 # 4 trophLand["Crabs", "xval"] = 6.1 trophLand["Geoduck", "xval"] = 0.6 # 1 trophLand["Scallops", "xval"] = 5.0 # 6 trophLand["Abalone", "xval"] = 7.0 trophLand["Sea Cucumbers", "xval"] = 0 trophLand["Sea Urchins", "xval"] = 2.7 trophLand["Other Echinoderms", "xval"] = 2.2 trophLand["Shrimp", "xval"] = 6.7 trophLand["Prawns", "xval"] = 8.5 trophLand["Squid & Octopus", "xval"] = 6 # trophLand["Clams.cult", "xval"] = 3 # trophLand["Oysters.cult", "xval"] = 4 # trophLand["Scallops.oth.cult", "xval"] = 5 trophLand["Tuna", "xval"] = 2 trophLand["Sardines", "xval"] = 11 # trophLand["Other", "xval"] = # trophLand["Other.cult", "xval"] = trophLand["Toothed Whales", "xval"] = 9 trophLand["Baleen Whales", "xval"] = 9 trophLand["Sharks", "xval"] = 0 trophLand["Seals", "xval"] = 3 trophLand["Sea Lions", "xval"] = 6 trophLand["Birds", "xval"] = 5.5 trophLand["Lanternfish", "xval"] = 4.7 trophLand["Phytoplankton", "xval"] = 1.9 trophLand["Macroalgae", "xval"] = 5 trophLand["Seagrasses", "xval"] = 8.1 trophLand["Microzooplankton", "xval"] = 1.9 trophLand["Mesozooplankton", "xval"] = 5 # mean(trophLand[c("Phytoplankton", "Macroalgae"), "xval"]) - 0.5 trophLand["Shelled Pteropods", "xval"] = 8.1 #trophLand["Macroalgae", "xval"]+0.8 trophLand["Euphausiids", "xval"] = 9.0 trophLand["Naked Pteropods*", "xval"] = trophLand["Microzooplankton", "xval"] trophLand["Corals", "xval"] = 10 trophLand["Glass Sponges", "xval"] = 9.7 noTrophic = is.na(trophLand$trophic) xMax = 12 xLim = c(0,xMax) # range( trophLand[!noTrophic, "xval"]) + c(0,1) # may be worth hardwiring if(max(trophLand[!noTrophic,"xval"]) > xMax) stop("max(xval) is too big") # Colours will represent potential *direct* impact of OA # effects, based on our manuscript. # Impact on the species group: good = "blue" neutral = "yellow" bad = "red" nodata = "grey" # notSureYet = "white" # Haven't looked into. # Dummy for now # trophLand$OAeffect = rep(c("red", "yellow", "blue"), length=dim(trophLand)[1]) # Commenting out if trophic==NA (so not on figure yet), but will # probably want to include these (have a landed value for them, just not a # trophic level). Copying from xval above. Giving justification in comment # if necessary, or see the relevant part of the manuscript. trophLand["Chinook", "OAeffect"] = nodata trophLand["Chum", "OAeffect"] = nodata trophLand["Coho", "OAeffect"] = nodata trophLand["Pink*", "OAeffect"] = nodata # possibly -ve, adding dots later trophLand["Sockeye", "OAeffect"] = nodata trophLand["Atlantic.cult", "OAeffect"] = nodata trophLand["Pacific.cult", "OAeffect"] = nodata trophLand["Herring", "OAeffect"] = nodata # Franke and Clemensen is Atl. Herr. # so maybe mention but not use here trophLand["Arrowtooth", "OAeffect"] = nodata trophLand["Dogfish", "OAeffect"] = nodata trophLand["Hake", "OAeffect"] = nodata trophLand["Halibut", "OAeffect"] = nodata trophLand["Lingcod", "OAeffect"] = nodata trophLand["Pacific Cod", "OAeffect"] = nodata trophLand["Pollock", "OAeffect"] = neutral # see manuscript trophLand["Rockfish", "OAeffect"] = nodata trophLand["Sablefish", "OAeffect"] = nodata trophLand["Sole", "OAeffect"] = nodata # trophLand["Other.groundfish", "OAeffect"] = trophLand["Clams", "OAeffect"] = bad # see manuscript trophLand["Crabs", "OAeffect"] = nodata # possibly -ve, adding dots later trophLand["Geoduck", "OAeffect"] = bad trophLand["Scallops", "OAeffect"] = bad trophLand["Abalone", "OAeffect"] = bad trophLand["Sea Cucumbers", "OAeffect"] = bad trophLand["Sea Urchins", "OAeffect"] = bad trophLand["Other Echinoderms", "OAeffect"] = bad trophLand["Shrimp", "OAeffect"] = nodata trophLand["Prawns", "OAeffect"] = nodata trophLand["Squid & Octopus", "OAeffect"] = nodata trophLand["Clams.cult", "OAeffect"] = bad trophLand["Oysters.cult", "OAeffect"] = bad trophLand["Scallops.oth.cult", "OAeffect"] = bad trophLand["Tuna", "OAeffect"] = nodata trophLand["Sardines", "OAeffect"] = nodata # trophLand["Other", "OAeffect"] = trophLand["Other.cult", "OAeffect"] = nodata trophLand["Toothed Whales", "OAeffect"] = nodata trophLand["Baleen Whales", "OAeffect"] = nodata trophLand["Sharks", "OAeffect"] = nodata trophLand["Seals", "OAeffect"] = nodata trophLand["Sea Lions", "OAeffect"] = nodata trophLand["Birds", "OAeffect"] = nodata trophLand["Lanternfish", "OAeffect"] = nodata trophLand["Naked Pteropods*", "OAeffect"] = bad # now naked Pteropods # (whose only food source is shelled Pteropods), # so calling bad based on this indirect effect # based on Debby's write up. trophLand["Phytoplankton", "OAeffect"] = good trophLand["Macroalgae", "OAeffect"] = bad # Carrie's write up all +ve, adding half +ve below trophLand["Seagrasses", "OAeffect"] = neutral trophLand["Microzooplankton", "OAeffect"] = bad # Rowan's write up, # doing as neutral and bad below. trophLand["Mesozooplankton", "OAeffect"] = nodata # Neutral and # likely -ve (low certainty = stipple), # doing manually below trophLand["Shelled Pteropods", "OAeffect"] = bad trophLand["Euphausiids", "OAeffect"] = nodata trophLand["Corals", "OAeffect"] = nodata # Debby, plus stipples trophLand["Glass Sponges", "OAeffect"] = nodata # Debby. #======================== # FARMED SPECIES #======================== # Now for figure for farmed species, keeping scaling the same, which works # because Atlantic.cult has the biggest landed value. farmLand = trophLand[row.names(trophLand) %in% c("Atlantic.cult", "Pacific.cult", "Clams.cult", "Oysters.cult", "Scallops.oth.cult", "Other.cult"),] # Now including "Other.cult" as such a mixture, and listing in figure trophLandNoTrophic = trophLand[is.na(trophLand$trophic), ] # NA trophic levels trophLandNoTrophic = trophLandNoTrophic[-match(c("Atlantic.cult", "Pacific.cult", "Clams.cult", "Oysters.cult", "Scallops.oth.cult", "Other.cult"), row.names(trophLandNoTrophic)),] # take out ones that are used in cultured figure. # Renaiming rows here for figure, keeping them as they were in trophLand (here # we don't need to say .cult, as that will be in the figure header/caption row.names(farmLand)[row.names(farmLand) %in% "Atlantic.cult"] = "Atlantic Salmon*" row.names(farmLand)[row.names(farmLand) %in% "Pacific.cult"] = "Pacific Salmon*" row.names(farmLand)[row.names(farmLand) %in% "Clams.cult"] = "Clams" row.names(farmLand)[row.names(farmLand) %in% "Oysters.cult"] = "Oysters" row.names(farmLand)[row.names(farmLand) %in% "Scallops.oth.cult"] = "Scallops & Other Shellfish" row.names(farmLand)[row.names(farmLand) %in% "Other.cult"] = "Other:" otherIndex = which(row.names(farmLand) %in% "Other:") salmonTroph = mean(trophLand[c("Chinook", "Chum", "Coho", "Pink*", "Sockeye"), "trophic"]) farmLand$xval = c(2, 6.6, 4.0, 2, 6.0, 8.6) # Where to plot wrt x-axis farmLand$yval = c(salmonTroph, salmonTroph, trophLand["Clams","trophic"], trophLand["Clams","trophic"], trophLand["Clams","trophic"], 3.5) # Where to plot wrt y-axis #======================== # CONSTRUCT THE FIGURE #======================== # Original, par("pin") = 6.26, 4.50, with fig.width=7.5, fig.height=5. # Want to expand y axis, from yLim = c(1,5), but keep absolute # size of what was there the # same. Keep 0.5 inches total above and below. Though seemed to be 0.7 # for farmed. # (defined in par(mai = ...) below). Actually, don't need to be exact. #fig.width = 7.5 #fig.height = 5 * 1.05 # PLOS ONE figures -- dimensions: # Minimum: 8.3cm (3.27in) W # Maximum: 17.35cm (6.83in) W x 23.35cm (9.19in) H fig.name = "OAtrophfig4" fig.width = 6.8 # should be 6.83 absolute max, was 7.5 fig.height = 9 # 9.19 is max but will include the caption. circleInch = 0.8 # size of biggest circle, square then scales to it squareInch = 0.18 # was 0.2, RH said looked a bit big. # 0.3*circleInch # yLim = c(floor(min(trophLand$trophic, na.rm=TRUE)), # ceiling(max(trophLand$trophic, na.rm=TRUE))) # == c(1,5) yLim = c(0.83, 5) # Constructing six identical figures saved as different formats. for(i in 1:6) { switch(i, { postscript(paste(fig.name, "Arial.eps", sep=""), horizontal=FALSE, paper="special", height = fig.height, width = fig.width, family="Arial", onefile=FALSE)}, # onefile=F for Arial { postscript(paste(fig.name, ".eps", sep=""), horizontal=FALSE, paper="special", height = fig.height, width = fig.width, family="Helvetica")}, { png(paste(fig.name, ".png", sep=""), res=300, height = fig.height, width = fig.width, units="in")}, # horizontal=FALSE, paper="special" { win.metafile(paste(fig.name, ".wmf", sep=""), height = fig.height, width = fig.width)}, { tiff(paste(fig.name, ".tiff", sep=""), height = fig.height, width = fig.width, units="in", res=400, compression="lzw") }, # think res is dpi, this is what I used for # previous paper PLOS ONE,7(10): e45174 { pdf(paste(fig.name, "Arial.pdf", sep=""), paper="special", height = fig.height, width = fig.width, family="Arial", onefile=FALSE)} # onefile=F needed for Arial ) oldmai = par("mai") # 1.02 0.82 0.82 0.42 par(mfrow=c(2,1), mai = c(0.1,0.5,0.3,0.1), omi=c(0,0,0,0), mgp=c(1.4,0.6,0), las=1) # so keep left and right the same, then 0.1 is taken off bottom here # (as no x label) and taken off top of second figure. Adding 0.5 to # top of this and bottom of second one and 1 inch to toal height so # it prints out okay. # trophLand["Atlantic.cult", "value"] = 10 # to see if symbols scales to # the original value, even # though it's not used # (trophic=NA). Yes it does. # Empty plot so can then add y axis but not x (axes=FALSE doesn't work in # symbols): plot(1, type="n", axes=FALSE, xlim=xLim, ylim=yLim, xlab="", ylab="Trophic level", main="Wild species groups", cex.lab=1.1) #print(par("pin")) symbols(trophLand$xval, trophLand$trophic, circles=sqrt(trophLand$value), bg=trophLand$OAeffect, inches=circleInch, add=TRUE) # inches=FALSE makes it scale with x axis, circleInch scales # largest value to be that big - seems better. # Did have circles=sqrt... *circleScale, but best to fix # biggest, esp if axes change size. # circles default is to plot radii proportional to the data # (generally recommended way). But here doing # sqrt(..value) so areas are proportional, which looks # better here (just not as visually accurate). Scales to # largest (Atlantic.cult) in data set, even if that doesn't # get plotted, since no trophic level. axis(2, at=1:ceiling(max(trophLand$trophic, na.rm=TRUE))) # tcl=-0.2) text(12.3,5.05,"A",cex=2,adj=c(1,1)) box() # axis(1) # to see xvals, but then delete # Squares for groups that have a trophic level but no landed value noValue = is.na(trophLand$value) symbols(trophLand[noValue, "xval"], trophLand[noValue, "trophic"], squares=rep(1, sum(noValue)), bg=trophLand[noValue, "OAeffect"], add=TRUE, inches=squareInch) # Adding stippling for corals, mesozooplankton, Pink Salmon and crabs. # Could write function but just copy legend # code here and modify manually, though need Pink as a circle. points( rep(trophLand["Corals", "xval"], 4) + squareInch*0.9*0.63* c(-1, 1, -1, 1), rep(trophLand["Corals", "trophic"], 4) + squareInch*0.9*0.27* c(-1, -1, 1, 1), pch=20, col="red", cex=0.4) points( rep(trophLand["Mesozooplankton", "xval"], 4) + squareInch*0.9*0.63* c(-1, 1, -1, 1), rep(trophLand["Mesozooplankton", "trophic"], 4) + squareInch*0.9*0.27* c(-1, -1, 1, 1), pch=20, col="red", cex=0.4) # This then has 2nd half # Adding stippling for 'possible -ve effects'. First attempt didn't work, but # since circle here is same size as squares, just do this manually. Didn't work # because the centre of the circle does not lie on one of the grid points of # PinP. #PinP(a = trophLand["Pink*", "xval"], b = trophLand["Pink*", "trophic"], # r = 0.9*circleInch * sqrt(trophLand["Pink*", "value"]) / sqrt(trophLandMaxVal)) # 0.9 just to tweak, remove some of the outside dots points( rep(trophLand["Pink*", "xval"], 4) + squareInch*0.9*0.63* c(-1, 1, -1, 1), rep(trophLand["Pink*", "trophic"], 4) + squareInch*0.9*0.27* c(-1, -1, 1, 1), pch=20, col="red", cex=0.4) PinP(a = trophLand["Crabs", "xval"], b = trophLand["Crabs", "trophic"], r = 0.975* circleInch * sqrt(trophLand["Crabs", "value"]) / sqrt(trophLandMaxVal)) # Rectangles to make some squares two colours: addNeutral = (row.names(trophLand) %in% c("Microzooplankton", "Mesozooplankton")) symbols(trophLand[addNeutral, "xval"] - 0.1, trophLand[addNeutral, "trophic"], rectangles=matrix(c(0.5,1), nrow=sum(addNeutral), ncol=2, byrow=TRUE), bg=neutral, add=TRUE, inches=squareInch) # -0.1 on xval seems to work, not same unit as inches though. addGood = (row.names(trophLand) %in% c("Macroalgae")) # based on Carrie's text symbols(trophLand[addGood, "xval"] - 0.1, trophLand[addGood, "trophic"], rectangles=matrix(c(0.5,1), nrow=sum(addGood), ncol=2, byrow=TRUE), bg=good, add=TRUE, inches=squareInch) # -0.1 on xval seems to work, not same unit as inches though. # Add columns to trophLand to tweak each label in x and y directions and then # add them on here in place of zeros: offset = sqrt(trophLand$value)/25 # +100*(trophLand$value > 10) # offset based on radius of circle/square. offset[is.na(offset)] = 0.07 # 0.1 when squareInch=0.2; 0.08 when 0.18. But # making smaller now fig.width is smaller. textPosX = trophLand$xval + offset + (row.names(trophLand) %in% c("Crabs", "Sablefish", "Rockfish", "Prawns", "Tuna"))*0.07 + (row.names(trophLand) %in% c("Halibut", "Geoduck"))*0.09 + (row.names(trophLand) %in% c("Pacific Cod", "Shrimp"))*(-0.09) + (row.names(trophLand) %in% c("Sole", "Herring", "Sardines", "Pollock"))*(-0.07) # shift for larger circles, and as needed textPosY = trophLand$trophic + 0 cexVal = 0.8 text(textPosX, textPosY, row.names(trophLand), pos=4, cex=cexVal) #, offset=offset)- 1st element only # Now for farmed fish figure. # Empty plot (axes=FALSE doesn't work in symbols). For this fig prob no labelling# on axes, but want figure the same size as the wild fisheries one. plot(1, type="n", axes=FALSE, xlim=xLim, ylim=yLim, xlab="", ylab="Trophic level", main="Farmed species groups", cex.lab=1.1) #print(par("pin")) symbols(farmLand$xval, farmLand$yval, circles=sqrt(farmLand$value), bg=farmLand$OAeffect, inches=circleInch, add=TRUE) # inches=FALSE makes it scale with x axis, circleInch scales # largest value to be that big - seems better. # Did have circles=sqrt... *circleScale, but best to fix # biggest, esp if axes change size. # circles default is to plot radii proportional to the data # (generally recommended way). But here doing # sqrt(..value) so areas are proportional, which looks # better here (just not as visually accurate). # After I changed par("mai")[1], I'm not sure why this isn't exact - is # giving circles, but 0.9 for "Pac" gives the exact same as from symbols. # Since circles are working, just tweak the r value to give correct answer. PinP(a = farmLand["Atl", "xval"], b = farmLand["Atl", "yval"], r = circleInch*1.05)#*0.93) # 0.98 just to tweak, remove some of the outside dots # sqrt(farmLand["Atl", "value"])) # Adding stippling for 'possible -ve indirect' PinP(a = farmLand["Pac", "xval"], b = farmLand["Pac", "yval"], r = 0.9* circleInch * sqrt(farmLand["Pac", "value"]) / sqrt(trophLandMaxVal)) axis(2, at=1:ceiling(max(trophLand$trophic, na.rm=TRUE))) # tcl=-0.2) text(12.3,5.05,"B",cex=2,adj=c(1,1)) box() # axis(1) # to see xvals, but then delete # Add columns to trophLand to tweak each label in x and y directions and then # add them on here in place of zeros: farmOffset = sqrt(farmLand$value)/20 # +100*(trophLand$value > 10) # offset based on radius of circle/square. # farmOffset[is.na(farmOffset)] = 0.1 farmTextPosX = farmLand$xval + farmOffset + c(0.5, 0, 0, 0, 0, 0) farmTextPosY = farmLand$yval + 0 # Manually adjust some: # offset[row.names(trophLand) in c(" cexVal = 0.8 text(farmTextPosX, farmTextPosY, row.names(farmLand), pos=4, cex=cexVal) #, offset=offset)- 1st element only text(farmTextPosX[match("Pacific Salmon", row.names(farmLand))] + 0.2, farmTextPosY[match("Pacific Salmon", row.names(farmLand))] - 0.15, "(Chinook, Coho, Sockeye)", pos=4, cex=cexVal) text(rep(farmTextPosX[otherIndex]+1, 7), farmTextPosY[otherIndex] + seq(0, by=-0.2, length=7), c("Sablefish", "Sturgeon", "Tilapia", "Crayfish", "Abalone", "Sea Cucumbers", "Marine Plants"), cex=cexVal, pos=4) # and freshwater trout - leaving out since freshwater # May want to do square and circles in colours. Will manually do legend. squareLegSize = 0.18 # squareInch*0.9 # X-axis width of squares for legend. rectLegSize = c(0.30,0.10) xLeg = rep(10.7,2) # text(xLeg[1], 4.85, "($million)", pos=4, cex=cexVal) yLeg = c(1.6, 1.8)-0.2 valsLeg = c(1, 10) # circles scale to largest value, need to match # with above. Text not automated with these numbers #text(xLeg[1]-0.5, yLeg[1]+0.4, "Landed value", pos=4, cex=cexVal, # font=2) # font=2 is bold text(xLeg[1]-0.5, yLeg[1]+0.4+0.025, "Landed value", pos=4, cex=cexVal, font=2) # font=2 is bold symbols(xLeg, yLeg-c(0.03, 0), circles=sqrt(valsLeg), inches=circleInch * sqrt(max(valsLeg) / max(trophLand$value, na.rm=TRUE)), add=TRUE) text(xLeg, yLeg-c(0.03, 0), c(" $1 million", " $10 million"), pos=4, cex=cexVal) yLegOAtop = yLeg[1]+0.4 #0.4 yLegOA = yLegOAtop - c(0.2, 0.4, 0.6, 0.8, 1.0) xLegOA = rep(xLeg[1]-2.9, length(yLegOA)) text(xLegOA[1]-0.45, yLegOAtop+0.025, "Acidification effect", pos=4, cex=cexVal, font=2) symbols(xLegOA, yLegOA, #squares=rep(1, length(yLegOA)), rectangles = matrix(rep(rectLegSize,each=length(yLegOA)),ncol=2), fg=NA, bg=c(good, neutral, bad, nodata, nodata), add=TRUE, inches=0.25) # centres are xLegOA, width in x axis is given by 'inches' text(xLegOA, yLegOA, c(" Likely positive", " Likely neutral", " Likely negative", " Possibly negative (low certainty)", " Unknown"), pos=4, cex=cexVal) points( rep(xLegOA[4], 2) + squareLegSize*0.63*c(-1, 1), rep(yLegOA[4], 2) + squareLegSize*0.27*c(0, 0), pch=20, col="red", cex=0.4) # Stippling, yscaling worked out # by trial and error lines(c(xLegOA[1]-0.4, xLegOA[1]-0.4, 13), c(0, 2.0, 2.0), col="darkgrey") dev.off() } # end of loop to do each kind of figure # Some summariy calculations of interest: # To check what we left out: # print("trophLandNoTrophic") # print(trophLandNoTrophic) # print("preikNoValue") # print(preikNoValue) # landed[landed$Landed.value > 25,] # landed value total for molluscs: molluscs = c("Clams", "Geoduck", "Scallops", "Clams.cult", "Oysters.cult", "Scallops.oth.cult", "Squid & Octopus") molluscLand = sum(trophLand[molluscs, ]$value) GeoduckProp = trophLand["Geoduck", "value"]/ molluscLand #% 66% # sort to see highest landed values: trophLandByValue = trophLand[with(trophLand, order(-value)),] # row.names(trophLandByValue[c(2:7,9),]) # gives top ones above $25mill, but take out Pacific.cult # (and starting at 2 takes out Atlantic.cult) # Trophic levels ,just those <3.1 then ordered: # xx = trophLand[(trophLand$trophic < 3.1 & !is.na(trophLand$trophic)), ] # ["trophic"] # xx[order(xx$trophic),,drop=FALSE] # For caption: ....trophic levels, which are adapted from the BC shelf output from Preikshot (2007 [PhD]). # \caption{Summary of likely direct effects of ocean acidification on fished and unfished species groups in British Columbia waters, including landed value for those that are fished. Species groups are arranged by trophic levels, which are adapted from the BC shelf outpur from \citet{Preikshot:2007}. Areas of circles are proportional to the landed values in 2011 (wild fisheries only), based on data in \citep{BCAgriculture:2012}. Squares represent species groups that are not commercially fished. Colours represent the likely effects of ocean acidification, based on our review of the literature (see text for details). Naked Pteropods are likely to be negatively affected due to indirect effects (indicated by *), since their diet is almost exclusively Shelled Pteropods, which are themselves likely to be directly negatively affected. Squid and Octopus also includes other unspecified shellfish.} save.image("OAtrophfig4.RData")