How to make a faceted cell graph in ObservableHQ? - d3.js

I have the following array of objects:
[{ "userid": 1, "groupid": 66123, "date_joined": "2023-01-01", "d0": "10", "d1": "6", "d2": "0", "d3": "1", "d4": "0", "d5": "0", "d6": "0", "d7": "0", "d8": "0", "d9": "0", "d10": "0", "d11": "0", "d12": "0", "d13": "0", "d14": "0" },
{ "userid": 2, "groupid": 66123, "date_joined": "2023-01-01", "d0": "0", "d1": "0", "d2": "2", "d3": "0", "d4": "0", "d5": "0", "d6": "0", "d7": "0", "d8": "0", "d9": "0", "d10": "0", "d11": "0", "d12": "0", "d13": "0", "d14": "0" },
{ "userid": 3, "groupid": 68100, "date_joined": "2023-01-01", "d0": "0", "d1": "0", "d2": "0", "d3": "0", "d4": "0", "d5": "0", "d6": "0", "d7": "0", "d8": "0", "d9": "0", "d10": "0", "d11": "0", "d12": "0", "d13": "0", "d14": "0" }]
and I want to create a faceted cell graph like the following:
where:
each facet is determined by the "groupid"
each row in the facet is the "userid"
there are 15 blocks on each row, corresponding to the respective "d0" - "d14" columns.
Example:
The first facet would be for groupid "66123", with two rows: userid "1" and userid "2". Each row would have 15 columns, each one corresponding to the respective "d0" - "d14" columns.
This code is from the example notebook:
Plot.plot({
height: 1400,
x: {
axis: null,
padding: 0,
},
y: {
padding: 0,
tickFormat: Plot.formatWeekday("en", "narrow"),
tickSize: 0
},
fy: {
reverse: true
},
facet: {
data: DJI,
y: d => d.Date.getUTCFullYear()
},
color: {
type: "diverging",
scheme: "PiYG"
},
marks: [
Plot.cell(DJI, {
x: d => d3.utcWeek.count(d3.utcYear(d.Date), d.Date),
y: d => d.Date.getUTCDay(),
fill: (d, i) => i > 0 ? (d.Close - DJI[i - 1].Close) / DJI[i - 1].Close : NaN,
title: (d, i) => i > 0 ? ((d.Close - DJI[i - 1].Close) / DJI[i - 1].Close * 100).toFixed(1) : NaN,
inset: 0.5
})
]
})
I'm not sure how to change the x: d => d3.utcWeek.count(d3.utcYear(d.Date), d.Date), with to get the graph that I need.
Any help would be greatly appreciated!

Can I suggest that you share a notebook with what you have tried so far? It will be easier to help you if we see where you're at.

Related

Laravel MongoDB unset use?

{
"_id": {
"$oid": "60b609d6bd846108dc86433d"
},
"il": "Siirt",
"ilce": "merkez",
"ada": 466,
"parsel": 1,
"pafta": "M47-B-09-B-3-A",
"tkgmkodu": "106478407",
"tkgmeskikodu": [],
"nitelik": "Tarla",
"tapualani": "621,54",
"cadde": "",
"sokak": "",
"mahalle": "",
"kiracilar": [{
"_id": {
"$oid": "60b609d6bd846108dc86431d"
},
"durum": 1,
"adi": "kiraci Adı",
"soyadi": "kiraci soyadi",
"tc": "456454654654",
"tel": "5424210910",
"blok": "b",
"kat": "5",
"d-no": 18,
"kayitTarihi": {
"$date": "2017-01-14T21:00:00.000Z"
},
"cikisTarihi": "",
"kiraTutari": 1000,
"notlar": "",
"borcAlacak": [{
"_id": {
"$oid": "60b609d6bd846408dc86433d"
},
"tarih": {
"$date": "2017-01-14T21:00:00.000Z"
},
"aciklama": "Ocak Ayı Borç Tahakkuku",
"bankaKodu": "",
"borc": 1000,
"odeme": 0
}, **{
"_id": {
"$oid": "632609d6bd846108dc86433d"
},
"tarih": {
"$date": "2017-01-15T21:00:00.000Z"
},
"aciklama": "Ocak Ayı Borç Ödemesidir.",
"bankaKodu": "ObjectId",
"borc": 0,
"odeme": 1000
}**]
}],
"mahkemeler": [""]
}
How I delete unset from MongoDB with Laravel use
I don't know what actually you use in laravel, but if you already have connection with mongoDB, you can delete it like this (using JS):
//replace with your id
let id_needed = '60b609d6bd846108dc86433d'
let deleted = req.db.collection('brands').deleteOne( { "_id" : ObjectId(id_needed)});

NiFi: ReplaceText alternatives to modify JSON

My NiFi application receives two kinda different types of JSON's.
First of them looks like:
[
{
"campaign": {
"resourceName": "customers/8952771329/campaigns/11381694617",
"status": "ENABLED",
"name": "Saint_Spring_Active Minerals_oct-nov_2020_trueview_skip_5766500views",
"id": "11381694617"
},
"metrics": {
"interactionEventTypes": [
"VIDEO_VIEW"
],
"clicks": "6",
"videoQuartileP100Rate": 0.44493171079034244,
"videoQuartileP25Rate": 0.9747718298919024,
"videoQuartileP50Rate": 0.7339309987701469,
"videoQuartileP75Rate": 0.5337562301767105,
"videoViewRate": 0.4471109114825628,
"videoViews": "27872",
"viewThroughConversions": "0",
"contentBudgetLostImpressionShare": 0.0000013066088274492382,
"contentImpressionShare": 0.0999,
"contentRankLostImpressionShare": 0.9001,
"conversionsValue": 0,
"conversions": 0,
"costMicros": "9338700950",
"ctr": 0.00009624947864865732,
"currentModelAttributedConversions": 0,
"currentModelAttributedConversionsValue": 0,
"engagementRate": 0,
"engagements": "0",
},
"segments": {
"device": "CONNECTED_TV",
"date": "2020-12-20"
}
}
]
And second:
[
{
"adGroup": {
"resourceName": "customers/5404177717/adGroups/110501283582",
"campaign": "customers/5404177717/campaigns/11628802542"
},
"metrics": {
"interactionEventTypes": [
"CLICK"
],
"clicks": "1",
"averageCpm": 95497428.02172929,
"gmailForwards": "0",
"gmailSaves": "0",
"gmailSecondaryClicks": "0",
"impressions": "4418",
"interactionRate": 0.00022634676324128565,
"interactions": "1"
},
"adGroupAd": {
"resourceName": "customers/5404177717/adGroupAds/110501283582~480227690139",
"status": "ENABLED",
"ad": {
"resourceName": "customers/5404177717/ads/480227690139",
"id": "480227690139",
"name": "20 sec perek"
},
"adGroup": "customers/5404177717/adGroups/110501283582"
},
"segments": {
"device": "DESKTOP",
"date": "2020-11-21"
}
}
]
I already have 2 tables in my database to save this data. I have an attribute table.name just to not create same block where's only table name is different.
My next block is FlattenJson. After this i'm using ReplaceText with search value (replacement value is empty string): (customers\\\/${client.customer.id}\\\/campaigns\\\/|customers\\\/${client.customer.id}\\\/adGroups\\\/).
Why this? From this line: "adGroup": "customers/5404177717/adGroups/110501283582" i only need last value 110501283582 as ad_group_id. And from this line: "campaign": "customers/5404177717/campaigns/11628802542" i only need 11628802542. ${client.customer.id} can be different, so i'm using EL features.
Also i need to change json value name adGroup to ad.group.id, for this i'm also using ReplaceText.
Can i do it faster without two ReplaceText processors?
Look at the following processors...I think using them can be an alternative:
JoltTransformJSON:
https://nifi.apache.org/docs/nifi-docs/components/org.apache.nifi/nifi-standard-nar/1.5.0/org.apache.nifi.processors.standard.JoltTransformJSON/
UpdateRecord:
https://nifi.apache.org/docs/nifi-docs/components/org.apache.nifi/nifi-standard-nar/1.5.0/org.apache.nifi.processors.standard.UpdateRecord/index.html

swift get currencycode from country code

I find the accepted answer to get currencycode from country code in objective c here - How to get ISOCurrencyCode from a ISOCountryCode in iphone sdk?
Can someone help with the swift code to do the same ?
let components: [String: String] = [NSLocaleCountryCode: "CA"]
let identifier = NSLocale.localeIdentifierFromComponents(components)
let locale = NSLocale(localeIdentifier: identifier)
let currencyCode = locale.objectForKey(NSLocaleCurrencyCode)
print(currencyCode)
public static func convertStringCurrencyToNumber(strCurrency:String, locale:String)->Double {
var formatter = NSNumberFormatter()
formatter.currencyCode = locale
formatter.numberStyle = NSNumberFormatterStyle.CurrencyStyle
if let converted:Double = formatter.numberFromString(strCurrency)?.doubleValue {
return converted
}else{
return 0.0
}
}
Changing formatter.locale to formatter.currencyCode works as expected with the ISO 4127 Country and Currency code "USD".
Use below this return type function to get country_code:-
//MARK:- GET COUNTRY CODE
func getCountryPhonceCode (_ country : String) -> String
{
let x : [String] = ["972", "IL",
"93" , "AF",
"355", "AL",
"213", "DZ",
"1" , "AS",
"376", "AD",
"244", "AO",
"1" , "AI",
"1" , "AG",
"54" , "AR",
"374", "AM",
"297", "AW",
"61" , "AU",
"43" , "AT",
"994", "AZ",
"1" , "BS",
"973", "BH",
"880", "BD",
"1" , "BB",
"375", "BY",
"32" , "BE",
"501", "BZ",
"229", "BJ",
"1" , "BM",
"975", "BT",
"387", "BA",
"267", "BW",
"55" , "BR",
"246", "IO",
"359", "BG",
"226", "BF",
"257", "BI",
"855", "KH",
"237", "CM",
"1" , "CA",
"238", "CV",
"345", "KY",
"236", "CF",
"235", "TD",
"56", "CL",
"86", "CN",
"61", "CX",
"57", "CO",
"269", "KM",
"242", "CG",
"682", "CK",
"506", "CR",
"385", "HR",
"53" , "CU" ,
"537", "CY",
"420", "CZ",
"45" , "DK" ,
"253", "DJ",
"1" , "DM",
"1" , "DO",
"593", "EC",
"20" , "EG" ,
"503", "SV",
"240", "GQ",
"291", "ER",
"372", "EE",
"251", "ET",
"298", "FO",
"679", "FJ",
"358", "FI",
"33" , "FR",
"594", "GF",
"689", "PF",
"241", "GA",
"220", "GM",
"995", "GE",
"49" , "DE",
"233", "GH",
"350", "GI",
"30" , "GR",
"299", "GL",
"1" , "GD",
"590", "GP",
"1" , "GU",
"502", "GT",
"224", "GN",
"245", "GW",
"595", "GY",
"509", "HT",
"504", "HN",
"36" , "HU",
"354", "IS",
"91" , "IN",
"62" , "ID",
"964", "IQ",
"353", "IE",
"972", "IL",
"39" , "IT",
"1" , "JM",
"81", "JP", "962", "JO", "77", "KZ",
"254", "KE", "686", "KI", "965", "KW", "996", "KG",
"371", "LV", "961", "LB", "266", "LS", "231", "LR",
"423", "LI", "370", "LT", "352", "LU", "261", "MG",
"265", "MW", "60", "MY", "960", "MV", "223", "ML",
"356", "MT", "692", "MH", "596", "MQ", "222", "MR",
"230", "MU", "262", "YT", "52","MX", "377", "MC",
"976", "MN", "382", "ME", "1", "MS", "212", "MA",
"95", "MM", "264", "NA", "674", "NR", "977", "NP",
"31", "NL", "599", "AN", "687", "NC", "64", "NZ",
"505", "NI", "227", "NE", "234", "NG", "683", "NU",
"672", "NF", "1", "MP", "47", "NO", "968", "OM",
"92", "PK", "680", "PW", "507", "PA", "675", "PG",
"595", "PY", "51", "PE", "63", "PH", "48", "PL",
"351", "PT", "1", "PR", "974", "QA", "40", "RO",
"250", "RW", "685", "WS", "378", "SM", "966", "SA",
"221", "SN", "381", "RS", "248", "SC", "232", "SL",
"65", "SG", "421", "SK", "386", "SI", "677", "SB",
"27", "ZA", "500", "GS", "34", "ES", "94", "LK",
"249", "SD", "597", "SR", "268", "SZ", "46", "SE",
"41", "CH", "992", "TJ", "66", "TH", "228", "TG",
"690", "TK", "676", "TO", "1", "TT", "216", "TN",
"90", "TR", "993", "TM", "1", "TC", "688", "TV",
"256", "UG", "380", "UA", "971", "AE", "44", "GB",
"1", "US", "598", "UY", "998", "UZ", "678", "VU",
"681", "WF", "967", "YE", "260", "ZM", "263", "ZW",
"591", "BO", "673", "BN", "61", "CC", "243", "CD",
"225", "CI", "500", "FK", "44", "GG", "379", "VA",
"852", "HK", "98", "IR", "44", "IM", "44", "JE",
"850", "KP", "82", "KR", "856", "LA", "218", "LY",
"853", "MO", "389", "MK", "691", "FM", "373", "MD",
"258", "MZ", "970", "PS", "872", "PN", "262", "RE",
"7", "RU", "590", "BL", "290", "SH", "1", "KN",
"1", "LC", "590", "MF", "508", "PM", "1", "VC",
"239", "ST", "252", "SO", "47", "SJ",
"963","SY",
"886",
"TW", "255",
"TZ", "670",
"TL","58",
"VE","84",
"VN",
"284", "VG",
"340", "VI",
"678","VU",
"681","WF",
"685","WS",
"967","YE",
"262","YT",
"27","ZA",
"260","ZM",
"263","ZW"]
var keys = [String]()
var values = [String]()
let whitespace = CharacterSet.decimalDigits
//let range = phrase.rangeOfCharacterFromSet(whitespace)
for i in x {
// range will be nil if no whitespace is found
if (i.rangeOfCharacter(from: whitespace) != nil) {
values.append(i)
}
else {
keys.append(i)
}
}
let countryCodeListDict = NSDictionary(objects: values as [String], forKeys: keys as [String] as [NSCopying])
if let t: AnyObject = (countryCodeListDict as? [String : AnyObject])? [country] {
return countryCodeListDict[country] as! String
} else
{
return ""
}
}

Ruby json2csv fails

using
C:\RubyLearnToProgram>json2csv convert sample.json
results in following error:
Converting sample.json error: undefined method `keys' for
"PREPARED":String
The sample.json:
{
"preparationState": "PREPARED",
"consumerUsageStorageInstruction": {
"de": "gebruik",
"fr": "gebruik",
"en": "gebruik"
},
"npc": "1234",
"drainedWeight": "320.0GR",
"isBaseUnit": "true",
"packagingMarkedExpirationDateType": "BEST_BEFORE_DATE",
"numberOfServingsPerPackage": "100",
"functionalName": "Babbelaars",
"preparationInstructions": {
"de": "koken",
"fr": "koken",
"en": "koken"
},
"brandName": "Test lets try this one",
"manufacturerGln": "5060263871002",
"packagingRefuseObligationName": "ARA",
"gln": "5060263871002",
"height": "129.0MM",
"percentageOfAlcoholByVolume": "0.0",
"dailyValueIntakeReference": "10 a day keeps the doctor away",
"allergenStatement": {
"de": "Enthalt: Milch (Laktose)",
"fr": "Contient: lait de vache (lactose)",
"en": "Bevat: koemelk (lactose)"
},
"isPackagingMarkedReturnable": "false",
"netContent": "325.0GR",
"regulatedProductName": "Babbelaars",
"itemThumbnail": "/a/16257a91e7c42b64fdc7ad91292dce85/babbelaars.png",
"packages": [
{
"height": "100.0CM",
"containedGtin": "90000000000003",
"gtin": "91000000000002",
"width": "50.0CM",
"netContent": "100.0EA",
"packageUnitIndicator": "CASE",
"depth": "60.0CM",
"containedAmount": "10",
"grossWeight": "109.0KG"
}
],
"isVariableUnit": "false",
"taxRate": "STANDARD",
"width": "67.0MM",
"targetMarket": "528",
"gpc": "10000005",
"nameOfInformationProvider": "LANSA",
"depth": "67.0MM",
"grossWeight": "350.0GR",
"nutrients": [{
"percentageOfDailyValueIntake":"0.1","measurementPrecision":"APPROXIMATELY","quantityContainedServingSize":"1.0","quantityContainedHouseHoldServingSize":"10.0","quantityContainedUnit":"GR","nutrientTypeCode":"CHOAVL-"
},{
"percentageOfDailyValueIntake":"0.2","measurementPrecision":"APPROXIMATELY","quantityContainedServingSize":"2.0","quantityContainedHouseHoldServingSize":"20.0","quantityContainedUnit":"E14","nutrientTypeCode":"ENER-"
},{
"percentageOfDailyValueIntake":"0.3","measurementPrecision":"APPROXIMATELY","quantityContainedServingSize":"3.0","quantityContainedHouseHoldServingSize":"30.0","quantityContainedUnit":"GR","nutrientTypeCode":"FASAT"
},{
"percentageOfDailyValueIntake":"0.4","measurementPrecision":"APPROXIMATELY","quantityContainedServingSize":"4.0","quantityContainedHouseHoldServingSize":"40.0","quantityContainedUnit":"KJO","nutrientTypeCode":"ENER-"
},{
"percentageOfDailyValueIntake":"0.5","measurementPrecision":"APPROXIMATELY","quantityContainedServingSize":"5.0","quantityContainedHouseHoldServingSize":"50.0","quantityContainedUnit":"GR","nutrientTypeCode":"FIBTG"
},{
"percentageOfDailyValueIntake":"0.6","measurementPrecision":"APPROXIMATELY","quantityContainedServingSize":"6.0","quantityContainedHouseHoldServingSize":"60.0","quantityContainedUnit":"GR","nutrientTypeCode":"PRO-"
},{
"percentageOfDailyValueIntake":"0.7","measurementPrecision":"APPROXIMATELY","quantityContainedServingSize":"7.0","quantityContainedHouseHoldServingSize":"70.0","quantityContainedUnit":"GR","nutrientTypeCode":"FAT"
},{
"percentageOfDailyValueIntake":"0.8","measurementPrecision":"APPROXIMATELY","quantityContainedServingSize":"8.0","quantityContainedHouseHoldServingSize":"80.0","quantityContainedUnit":"GR","nutrientTypeCode":"SUGAR-"
},{
"percentageOfDailyValueIntake":"0.9","measurementPrecision":"APPROXIMATELY","quantityContainedServingSize":"9.0","quantityContainedHouseHoldServingSize":"90.0","quantityContainedUnit":"GR","nutrientTypeCode":"SALTEQ"
}],
"ingredientStatement": {
"de": "Zucker, Glukosesirup, Zuckersirup, Butter (3%), Salz.",
"fr": "sucre, sirop de glucose, sirop de sucre, beurre (3%), sel.",
"en": "sugar, glucose syrup, sugar syrup, butter (3%), salt."
},
"isItemReturnable": "false",
"shortDescription": {
"en": "Babbelaars"
},
"allergens": [
{
"allergenTypeCode": "BB",
"levelOfContainment": "CONTAINS"
}
],
"contactName": "LANSAEU1169",
"startAvailabilityDate": "2015-05-19",
"myattribute": "MyPostedEach",
"minimumLifespanFromTimeOfArrival": "8",
"householdServingSize": "household serving size",
"isDispatchUnit": "false",
"isBasePriceDeclarationRelevant": "false",
"allergenSpecificationAgency": "EU",
"isOrderableUnit": "false",
"allergenSpecificationName": "1169/2011",
"additives": [
{
"additiveName": "additive sample name",
"levelOfContainment": "CONTAINS"
}
],
"minimumLifespanFromTimeOfProduction": "10",
"baseUnitIndicator": "BASE_UNIT_OR_EACH",
"effectiveDate": "2015-05-19",
"servingSize": "GR",
"countryOfOrigin": "528",
"preparationType": "PRESSURE_COOKING",
"supplierItemNumber": "324324234",
"gtin": "90000000000003",
"pallets": [
{
"palletTypeCode": "37",
"height": "10.0MR",
"optionalGtin": "92000000000001",
"containedGtin": "91000000000002",
"palletTermsAndConditions": "3",
"width": "250.0CM",
"quantityOfLayersPerPallet": "5",
"palletUnitIndicator": "PALLET",
"depth": "120.0CM",
"containedAmount": "50",
"grossWeight": "1200.0KG",
"logisticsUnitStackingFactor": "10"
}
],
"barCodeType": "EAN_UCC_13_SYMBOL",
"nameOfManufacturer": "LANSA",
"compulsoryAdditivesLabelInformation": {
"de": "comp add label",
"fr": "comp add label",
"en": "comp add label"
},
"isInvoiceUnit": "false",
"isConsumerUnit": "true",
"packagingTypeCode": "CAN",
"communicationAddress": "Leliehof 26, 4841 ML PRINSENBEEK",
"itemImage": "/a/d59455129b92fb21dd00a97746a81439/babbelaars.png",
"isPackagingExemptFromRefuseObligation": "NOT_APPLICABLE"
}
Could you help me with this, I'm trying to get all keys and nested keys to create a dynamic conversion of values. Thanks in advance, Greetings Danny

Set Reference Points for Overlaying Data onto an image in R

I have seen a few questions on here (one was even by me) with respect to using R to plot an image.
The difference here is that I need to set the reference cooridnates for my image to match the data I am looking to plot on top of the image.
More specifically, I need R to understand that the coordinates for the background image are x = (-100,100) and y = (40,-40).
I have been able to to read in the image file and plot it using the ReadImages package, but when I overlay my data using points(), the data obviously do not line up appropriately.
Any help is much appreciated.
EDIT: here are some example data and I attached the image:
structure(list(teamid = c("6", "6", "6", "6", "6", "6", "2",
"6", "6", "6", "2", "6", "10", "10", "10", "10", "20", "20",
"10", "10", "10", "20", "20", "20", "10", "10"), xcoord = c("79",
"81", "33", "34", "75", "52", "-67", "80", "44", "79", "-53",
"54", "-55", "-81", "-66", "-66", "45", "81", "-78", "-70", "-59",
"50", "53", "63", "-79", "-78"), ycoord = c("0", "0", "-18",
"-20", "6", "-11", "-7", "7", "-28", "-10", "35", "22", "25",
"-5", "25", "23", "-11", "13", "22", "16", "13", "23", "7", "16",
"8", "8")), .Names = c("teamid", "xcoord", "ycoord"), class = "data.frame", row.names = c(74328L,
74331L, 74332L, 74334L, 74336L, 74338L, 74340L, 74341L, 74346L,
74347L, 74348L, 74349L, 100136L, 100137L, 100138L, 100139L, 100147L,
100148L, 100151L, 100154L, 100156L, 100158L, 100159L, 100161L,
100163L, 100167L))
You can create an empty plot with the correct dimensions, then use the rasterImage function to plot the image, then adding the points should work fine.
Another approach is to use the updateusr function from the TeachingDemos package after plotting the image to make sure that the coordinates match what you want them to before adding lines or points.
I saved your graphic above as ice.png and ran the following code:
library(EBImage)
ice <- readImage('My Pictures/ice.png')
pos <- structure(list(teamid = c("6", "6", "6", "6", "6", "6", "2",
"6", "6", "6", "2", "6", "10", "10", "10", "10", "20", "20",
"10", "10", "10", "20", "20", "20", "10", "10"), xcoord = c("79",
"81", "33", "34", "75", "52", "-67", "80", "44", "79", "-53",
"54", "-55", "-81", "-66", "-66", "45", "81", "-78", "-70", "-59",
"50", "53", "63", "-79", "-78"), ycoord = c("0", "0", "-18",
"-20", "6", "-11", "-7", "7", "-28", "-10", "35", "22", "25",
"-5", "25", "23", "-11", "13", "22", "16", "13", "23", "7", "16",
"8", "8")), .Names = c("teamid", "xcoord", "ycoord"),
class = "data.frame", row.names = c(74328L,
74331L, 74332L, 74334L, 74336L, 74338L, 74340L, 74341L, 74346L,
74347L, 74348L, 74349L, 100136L, 100137L, 100138L, 100139L, 100147L,
100148L, 100151L, 100154L, 100156L, 100158L, 100159L, 100161L,
100163L, 100167L))
pos$xcoord <- as.numeric(pos$xcoord)
pos$ycoord <- as.numeric(pos$ycoord)
ice2 <- as.raster(ice)
pin <- par('pin')
plot( c(-100,100), c(-40,40), type='n', xlab='', ylab='',
asp=pin[1]/pin[2], axes=FALSE, xaxs='i', yaxs='i')
rasterImage(ice2, -100, -40, 100, 40, interpolate=FALSE)
with(pos, text(xcoord, ycoord, teamid, col='green', cex=1.2) )
Does this do what you want?

Resources