[R] dotchart kleuren op basis van A>B?

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
The R Project for Statistical Computing

Ik zou graag een grafiek willen maken in R waarbij de kleur van de dots afhangt van de de waarde in een bepaalde column.
Dus als volgt:
De dots die de geplannede uren voorstellen krijgen een neutrale kleur. Blauw bijvoorbeeld. De dots die de gemaakte uren voorstellen krijgen de kleur rood of groen. Dit hangt af van het feit of de geplande uren overschreden zijn. In dit voorbeeld zouden alle dots van de Gemaakte uren dus Rood moeten zijn aangezien ze allemaal de geplande uren overschrijden.


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# Maak de volgende tabel:
#                 Activiteit A Activiteit B Activiteit C Activiteit D Activiteit E
# Geplande uren            1            2            3            4            5
# Gemaakte uren              6            7            8            9           10

uren <- matrix(
    c(1,2,3,4,5,6,7,8,9,10),
    ncol = 5,
    byrow = T
)

# Geef de matrix zijn rown namen
rownames(uren) <- c(
    "Geplande uren",
    "Gemaakte uren"
)

# Geef de matrix zijn column namen
colnames(uren) <- c(
    "Activiteit A",
    "Activiteit B",
    "Activiteit C",
    "Activiteit D",
    "Activiteit E"
    )

# Hiermee kan de marge van de figuur vergroot worden.
par(
    xpd=T,
    mar=par()$mar+c(0,0,0,0)
)
    
# maak een dot grafiek aan.
# col staat hier voor de kleuren:
# main is de titel
# xlab = x as label
dotchart(
    uren,
    col = c("blue", "red" ),
    main = "Dit is de Titel",
    xlab = "Tijdsbesteding in uren",
)

# Zet de marge weer terug op de default waarde:
par(
    mar= c(5,4,4,2) + 0.1
)


Er moet dus ergens een check inkomen.
Hier pseudo code die een het idee verder moet verduidelijken.

code:
1
2
3
4
5
6
7
8
if ( uren[geplande uren][x] < uren[gemaakte uren][x] )
{
    color dot[x] = "green"
}
else
{
    color dot[x] = "red"
}

Hier de grafiek in pdf formaat die ik tot nu toe heb
Hoe krijg ik dit voor elkaar?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Met wat programmeerwerk? Voor een zinnig topic in Programming zul je toch met een specifiekere vraag moeten komen dan "hoe moet dat". Laat zien wat je al hebt en waarom dat niet goed werkt / waarom je er niet uit komt.

[ Voor 4% gewijzigd door .oisyn op 18-05-2009 14:59 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Euhm Ik heb het idee uitgelegd? Dit is wat ik tot nu toe ehb. Ik zoek al een dag op internet. Ik heb zelf geeeen idee of dit uberhaupt mogelijk is (vast wel?) Als dit te weinig is om mij een duw in de goede richting te geven dan weet ik het ook niet meer.

Ik kan moeilijk laten zien wat ik al heb en wat niet werkt als ik niet weet hoe dat moet en ik dat ook niet op internet kan vinden?

Dit werkt dus bijvoorbeeld niet:
code:
1
2
3
4
5
6
7
8
9
10
# maak een dot grafiek aan.
# col staat hier voor de kleuren:
# main is de titel
# xlab = x as label
dotchart(
    uren,
    col = c("blue", ifelse(uren["Geplande uren"] < uren["Gemaakte uren"], "green", "red" ) ),
    main = "Dit is de Titel",
    xlab = "Tijdsbesteding in uren",
)

[ Voor 50% gewijzigd door Gehakt op 18-05-2009 15:18 ]


Acties:
  • 0 Henk 'm!

  • veldsla
  • Registratie: April 2000
  • Laatst online: 17-09 15:34
Die color vector wordt in de plot gerecycled. Als je die vector wat langer maakt kan je alle punten los kleuren.

code:
1
col=as.character(rbind(ifelse(uren["Geplande uren",] < uren["Gemaakte uren",],"green", "red"), "blue"))


doet denk ik wel wat je wilt

[ Voor 6% gewijzigd door veldsla op 18-05-2009 15:26 . Reden: matrix rijnummers vervangen door rijnamen ]


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Dat doet het perfect! Ik snap je code nog niet helemaal. Maar ik heb nu volgens mij wel het goede idee. Ipv een korte vector die telkens herhaald word geef je voor alle punten de kleuren apart op. Je maakt een soort van loop waarin je om en om test of het rood of groen moet zijn, daarna komt weer blauw etc?

Acties:
  • 0 Henk 'm!

  • veldsla
  • Registratie: April 2000
  • Laatst online: 17-09 15:34
Inderdaad. Die ifelse had je zelf al uitgevonden. Je was alleen de komma vergeten om de rijen eruit te halen voor de vergelijking. Na die ifelse heb je alleen de kleuren voor de de dynamisch gekleurde punten. Die moet je dan nog afwisselen met blauw. rbind maakt een matrix van de de input vectoren (en recycled ook indien nodig :)) en als je een matrix weer plat slaat met as.character dan gaat dat per kolom en zo kom je op de juiste vector.

Acties:
  • 0 Henk 'm!

  • veldsla
  • Registratie: April 2000
  • Laatst online: 17-09 15:34
code:
1
paste(ifelse(uren["Geplande uren",] < uren["Gemaakte uren",],"green", "red"), "blue")


is natuurlijk veel leesbaarder ;)

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Waarom zou je hier niet gewoon een barplot doen?
S:
1
2
3
barplot(uren, beside=TRUE,
    col=rbind(ifelse(uren["Geplande uren",] < uren["Gemaakte uren",], "green", "red"),
              "blue"))

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Ik heb over barplot, piechart en dotchart nagedacht en bekeken. Piechart valt af om dat ik overal lees dat het voor mensen moeilijker is om een hoek in te schatten dan een x aantal punten op ten opzichte van elkaar.
Daarnaast moet ik bij een barplot weer extra margin toevoegen aaan beide kanten.

Dit om de y as namen horizontaal weer te kunnen geven. En om een legende toe te voegen die aangeeft welke kleur bar de geplande/gemaakte uren zijn.

Ik vond de dotchart er het beste uitzien standaard. En ik heb ook ergens gelezen dat een dotchart minder misleidend is dan een barplot. simpelweg omdat je je alleen op het punt concentreert wat er toe doet(?).

Het eindresultaat moet een R script worden dat uit een MySQL database per week alle activiteiten netjes in een grafiek weer kan geven. Deze moeten netjes in pdf bestanden weggeschreven worden die ik vervolgens weer in latex verslagen kan opnemen.

Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Gehakt schreef op maandag 18 mei 2009 @ 21:44:
Daarnaast moet ik bij een barplot weer extra margin toevoegen aaan beide kanten.
Nu zet je de benodigde text per activiteit neer, wat natuurlijk behoorlijk veel ruimte inneemt op een pagina. Een legenda, met de tekst achter elkaar bijvoorbeeld onder de grafiek (of liever erin in een witruimte) zal veel minder ruimte innemen.
Ik vond de dotchart er het beste uitzien standaard. En ik heb ook ergens gelezen dat een dotchart minder misleidend is dan een barplot. simpelweg omdat je je alleen op het punt concentreert wat er toe doet(?).
Heb je een linkje? Dat zou ik zeer interessant vinden, maar ik kan het me nauwelijks voorstellen. Een volledige bar is toch makkelijker te spotten dan een enkel puntje. :) Het voordeel is wel dat je misschien minder snel afgeleid zal raken door de schaling van de assen, maar aangezien de relatieve lengte mij ook interessant lijkt in dit geval, lijkt me dat toch niet echt een voordeel hier.

Gelukkig hebben we de plaatjes nog:
Afbeeldingslocatie: http://img141.imageshack.us/img141/1576/barplot.png
Afbeeldingslocatie: http://img136.imageshack.us/img136/1426/dotplot.png

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • Gehakt
  • Registratie: Juli 2002
  • Laatst online: 19-09 15:50
Ik heb er nooit aan gedacht om de legende bij een barplot onder de figuur te zetten. Dit om dat ik niet wist dat je hem zo netjes plat (horizontaal) eronder kan krijgen. Ik geef toe dat die barplot er beter uit ziet.
Ik kan even geen link meer vinden over wat ik had gelezen met betrekking tot barplots en misleiding. Het kwam er volgens mij op neer dat de mens de lengte van de balk beoordeeld in plaats van het einde van de balk ten opzichte van het einde van een andere balk.
Ik probeer dit nog even op te zoeken.

Een andere vraag is nu hoe krijg je die y as labels horizontaal. Ik heb dat weleens voor elkaar gekregen maar ben vergeten hoe het moest.
Zelfde geld voor de legende. Hoe bepaal je hoe die netjes onder de grafiek komt en hoe krijg je hem horizontaal?
This plot is potentially misleading, because a strong visual ect in the plot is the comparison of the areas
of the shaded bars, which do not mean anything. This problem can be addressed by making the areas
proportional to the values they encode.

A better design is to altogether forego the bars, which distract from the primary comparison of the
end point positions, and instead use a dotplot.
Pagina 12
Ik weet niet of het ook van toepassing is op mijn data. Maar dat was onder andere een van de redenen om de dotplot te verkiezen boven de barplot.

* Ik ben er al achter dat je de legende simpelweg met HORIZ = T horizontaal kan krijgen.

[ Voor 33% gewijzigd door Gehakt op 19-05-2009 00:25 ]


Acties:
  • 0 Henk 'm!

  • pedorus
  • Registratie: Januari 2008
  • Niet online
Gehakt schreef op dinsdag 19 mei 2009 @ 00:05:
Een andere vraag is nu hoe krijg je die y as labels horizontaal. Ik heb dat weleens voor elkaar gekregen maar ben vergeten hoe het moest.
Helaas heb ik net de code weggegooid, uit mijn hoofd dus: :)
horiz=TRUE in dit geval, bij de meeste andere commando's is het horizontal=TRUE. En las=1 voor de labels, zie:
> ?par

En ik had even de set omgedraaid, uren=uren[,ncol(uren):1]
Zelfde geld voor de legende. Hoe bepaal je hoe die netjes onder de grafiek komt en hoe krijg je hem horizontaal?
Die had ik even handmatig goed gezet. Je kan iets als legend(0,-2,ncol=3, ...) gebruiken, maar die -2 zal dan steeds voor een andere positie zorgen als het aantal groepen niet gelijk is. Dit moet dus een berekening met het aantal groepen worden, of in zijn algemeenheid met par("usr").
Pagina 12
Ik weet niet of het ook van toepassing is op mijn data. Maar dat was onder andere een van de redenen om de dotplot te verkiezen boven de barplot.
Bedankt voor de link! Hetzelfde argument dus een beetje als wat ik gaf, maar gelukkig kun je hier de barplot bij 0 beginnen en dan is de lengte juist wel interessant. Ik vind die voorbeeldplots trouwens niet zo sterk, maar ik ben dan ook niet zo'n fan van lattice. Het is nu niet zo makkelijk om mannen en vrouwen te vergelijken.

Vitamine D tekorten in Nederland | Dodelijk coronaforum gesloten


Acties:
  • 0 Henk 'm!

  • veldsla
  • Registratie: April 2000
  • Laatst online: 17-09 15:34
pedorus schreef op dinsdag 19 mei 2009 @ 00:33:
Die had ik even handmatig goed gezet. Je kan iets als legend(0,-2,ncol=3, ...) gebruiken, maar die -2 zal dan steeds voor een andere positie zorgen als het aantal groepen niet gelijk is. Dit moet dus een berekening met het aantal groepen worden, of in zijn algemeenheid met par("usr").
Beetje offtopic maar, je legend staat buiten de plot region en dat wordt normaal geclipped. Je hebt dus ook met par(xpd) zitten spelen. Daarom lopen in je 2e plot de ablines ook verder dan de assen en door de labels!
Pagina: 1