- Kursmaterial
- Planering
- Arbete
- Kunskapsdokument
- Andra kurser
- Om Kursolle
6. Moment06 - Dataanalys
I detta moment ska vi arbeta med avancerade sätt att hantera data i Python. Vi fokuserar på kraftfulla tekniker som hjälper dig att hantera och analysera data på ett effektivt sätt. Dessa tekniker kommer inte bara att göra din kod kortare och tydligare, utan också hjälpa dig att lösa problem snabbare och enklare.
Info
Till detta moment finns en sida med lösningsförslag.
6.1 Avancerade listor och tupler
Nu ska vi fördjupa oss i hur man kan effektivisera och förbättra arbetet med listor och tupler i Python. Dessa tekniker ger dig möjlighet att göra mycket med lite kod, vilket minskar risken för fel och förbättrar läsbarheten.
6.1.1 List comprehension
List comprehensions gör det möjligt att skapa och filtrera listor mycket effektivt. En bra minnesregel när du använder list comprehension är:
[ uttryck for variabel in lista if villkor ]
Minnesregel:
- Börja med vad du vill göra med varje element (uttrycket).
- Ange därefter hur varje element hämtas från listan.
- Lägg eventuellt till ett villkor för filtrering.
Kodexempel: List comprehension
# Vanlig loop för att skapa kvadrater kvadrater = [] for x in range(1, 11): kvadrater.append(x2) # Samma kod med list comprehension kvadrater = [x2 for x in range(1, 11)] # Lagrar [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] # Filtrera fram jämna tal från en lista jämna_tal = [x for x in range(20) if x % 2 == 0] # Lagrar: [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Uppgift: m06u01
Skapa en lista med kuber av talen 1–20 med hjälp av list comprehension.
Uppgift: m06u02
Du har en lista med temperaturer: [18, 27, 22, 30, 15, 29]
. Filtrera ut alla temperaturer över 25 grader.
6.1.2 Tupler och tuple-unpacking
Tupler är fasta grupperingar av data där antalet element inte förändras. De är särskilt användbara när du vet exakt hur många värden du kommer att hantera. Tuple-unpacking låter dig enkelt extrahera data ur en tuple, detta är smidigt att använda om man vill returnera flera värden ur en funktion.
Kodexempel: Tuple-unpacking med funktion
# Funktion som returnerar flera värden i en tuple def koordinat(): return (4, 7) x, y = koordinat() print(f"Koordinaten är ({x}, {y})")
Tuple-unpacking är naturligtvis användbart på andra ställen i koden och inte bara i funktioner.
Kodexempel: Tuple-unpacking
# Direkt tuple-unpacking person = ("Olle", 16, "NA1") namn, ålder, klass = person print(f"{namn} är {ålder} år gammal och går i klass {klass}.")
Uppgift: m06u03
Skriv en funktion som returnerar högsta och lägsta temperaturen från listan [18, 27, 22, 30, 15, 29]
. Använd tuple-unpacking för att skriva ut resultaten.
6.1.3 Använda map()
och lambda
map()
används för att applicera en funktion på varje element i en lista. Resultatet är ett nytt objekt som du enkelt kan konvertera tillbaka till en lista med list()
.
Generell struktur för map()
map(funktion, lista)
- funktion är det som ska utföras på varje element (ofta en lambda-funktion).
- lista är listan vars element du vill ändra eller bearbeta.
Kodexempel: Användning av map()
och lambda
# Ursprunglig lista med temperaturer i Celsius celsius = [0, 10, 20, 30] # Omvandlar varje temperatur till Fahrenheit med hjälp av map och lambda fahrenheit = list(map(lambda c: c * 9/5 + 32, celsius)) # Resultat print(fahrenheit) # Skriver ut: [32.0, 50.0, 68.0, 86.0]
Förklaring
- Varje temperatur (
c
) multipliceras med9/5
och därefter adderas32
. - Detta görs automatiskt på varje element i listan.
- Resultatet samlas sedan upp i en ny lista.
list()
används för att typkonvertera ett map-objekt till en lista, eftersom ett map-objekt inte går att använda själv utan måste konverteras till något mer användbart, ofta en lista.
Vi kan också använda map()
och lambda för att typkonvertera elementen i en lista.
Kodexempel: Användning av map()
och lambda
# Ursprunglig lista med strängar strängar = ['1', '2', '3', '4'] # Konverterar varje sträng till ett heltal tal = list(map(lambda x: int(x), strängar)) # Resultat print(tal) # Skriver ut: [1, 2, 3, 4]
Förklaring
- Varje element (
x
) i listan är från början en sträng. int(x)
används för att konvertera varje sträng till ett heltal.- Resultatet samlas i en ny lista.
Funktionen map()
map är bra att kunna eftersom den hjälper dig att utföra samma operation på varje element i en lista utan att behöva skriva en loop varje gång. Detta gör din kod kortare, tydligare och lättare att läsa, och tillsammans med lambda-funktioner blir din kod ofta ännu mer kompakt och effektiv.
Uppgift: m06u04
Konvertera längder från meter till centimeter med hjälp av map()
och lambda. Använd denna listan: [1.5, 3.2, 7.8]
.
Uppgift: m06u05
Omvandla listan med fysikkonstanter ['3.14', '9.81', '6.626', '1.602']
från strängar till flyttal.
6.1.4 Filtrering och sortering med lambda
Lambda-funktioner är praktiska när du snabbt vill skapa enkla funktioner för sortering eller filtrering utan att definiera separata funktioner. Tupler rekommenderas eftersom data vanligtvis är fasta och oföränderliga men det går också att göra med lista i lista.
Kodexempel: Exempel med tuple
elever = [("Anna", 85), ("Björn", 72), ("Cecilia", 95)] sorterade_elever = sorted(elever, key=lambda elev: elev[1], reverse=True)
Kodexempel: Exempel med tuple
länder = [("Sverige", 10350000), ("Norge", 5400000), ("Island", 370000)] stora_länder = [land for land in länder if land[1] >= 1000000]
Uppgift: m06u06
Sortera följande kommuner efter folkmängd: kommuner = [('Göteborg', 600000), ('Borås', 115000), ('Alingsås', 42000), ('Lerum', 45000), ('Partille', 40000), ('Mölndal', 70000), ('Kungsbacka', 87000)]
Uppgift: m06u07
Från listan ovan, filtrera ut kommuner med folkmängd mindre än 50 000 invånare.
Uppgift: m06u08
När du har filtrerat ut kommuner med folkmängd mindre än 50 000 invånare så sortera denna listan från flest till minst antal invånare.
6.2 Dictionaries och JSON-strukturer
I det här avsnittet bygger vi vidare på det du lärde dig i moment05 om dictionaries och JSON. Vi arbetar med mer komplexa datastrukturer och tittar på hur vi kan spara och läsa data på ett effektivt sätt.
En dictionary i Python är ett sätt att koppla ihop två saker: en nyckel och ett värde. Det gör det lätt att strukturera information som hör ihop – till exempel en persons namn och ålder eller ett föremåls namn och pris.
6.2.1 Repetition och fördjupning om dictionaries
Dictionaries i Python lagrar data i form av nyckel–värde-par. Du kan enkelt hämta, lägga till, uppdatera och ta bort information i en dictionary.
Kodexempel: En enkel dictionary
person = { "namn": "Alva", "program": "NA", "poäng": 2400 } # Hämta ett värde print(person["namn"]) # Lägg till en ny nyckel person["klass"] = "NA22" # Uppdatera ett värde person["poäng"] += 100 # Iterera över dictionaryn for nyckel, värde in person.items(): print(f"{nyckel}: {värde}")
Utskrift
Alva namn: Alva program: NA poäng: 2500 klass: NA22
Här skapas en dictionary med information om en elev. Vi visar hur man hämtar ett värde, lägger till en ny nyckel, uppdaterar ett befintligt värde och loopar över alla nycklar och värden i dictionaryn.
Lägg märke till att du kan använda person["namn"]
för att hämta ett specifikt värde – precis som med listor, fast med namn istället för siffra.
Uppgift: m06u09
Skapa en dictionary för en elev med följande information:
- namn
- ålder
- program
- intressen (lista)
Skriv ut alla nyckel–värde-par med en loop.
6.2.2 JSON-strukturer
JSON (JavaScript Object Notation) är ett standardformat för att spara data – till exempel när du skickar information mellan olika program eller sparar information mellan körningar. I Python kan du enkelt omvandla dictionaries till JSON och tvärtom.
Det här är särskilt användbart när du vill lagra strukturerad data i en fil och senare kunna läsa in och analysera den.
Kodexempel: Konvertera dictionary till JSON-sträng
import json person = {"namn": "Alva", "program": "NA", "poäng": 2400} json_str = json.dumps(person, indent=2, ensure_ascii=False) print(json_str)
Funktionen json.dumps()
omvandlar en dictionary till en JSON-sträng. Parametern indent=2
gör att resultatet blir lättläst.
Om du vill att svenska tecken som å, ä och ö ska synas korrekt, kan du lägga till ensure_ascii=False
.
Utskrift
{ "namn": "Alva", "program": "NA", "poäng": 2400 }
Kodexempel: Spara och läsa från JSON-fil
import json person = {"namn": "Alva", "program": "NA", "poäng": 2400} # Spara till fil with open("elev.json", "w", encoding='utf-8') as fil: # ensure_ascii = False innebär att å/ä/ö sparas korrekt. json.dump(person, fil, indent=2, ensure_ascii=False) # Läsa från fil with open("elev.json", encoding='utf-8') as fil: data = json.load(fil) print(data) print(data["namn"])
Utskrift
{'namn': 'Alva', 'program': 'NA', 'poäng': 2400} Alva
elev.json
{ "namn": "Alva", "program": "NA", "poäng": 2400 }
Uppgift: m06u10
Skapa en dictionary för en bok med titel, författare och antal sidor. Spara den som en JSON-fil och läs sedan in den igen och skriv ut titel och antal sidor.
6.2.3 Komplexa datastrukturer
I mer avancerade program behöver man ofta kombinera listor och dictionaries. Ett vanligt exempel är att ha en lista av dictionaries, t.ex. en lista med elever eller mätdata.
Kodexempel: Lista med dictionarys
elever = [ {"namn": "Alva", "program": "NA"}, {"namn": "Elias", "program": "TE"}, {"namn": "Sara", "program": "NA"} ] for elev in elever: print(f"{elev['namn']} går {elev['program']}")
Nu har vi tagit steget vidare från enstaka dictionaries till en lista av dictionaries. Den här strukturen är vanlig när man vill hantera flera enheter av samma typ – t.ex. en lista av elever eller produkter i en butik.
Varje element i listan är en dictionary med samma uppsättning nycklar, vilket gör det lätt att loopa igenom och analysera datan.
Utskrift
Alva går NA Elias går TE Sara går NA
6.2.3.1 Sidospår: Shorthanded if (ternär operation)
När du vill tilldela en variabel ett värde baserat på ett enkelt villkor kan du använda en kompakt form som kallas shorthand if eller mer formellt: ternär operator.
Kodexempel: Shorthanded if
film = {"titel": "Inception", "tillåten_ålder": 15, "textad": True} textstatus = "har undertext" if film["textad"] else "har ingen undertext" print(f"{film['titel']} är tillåten från {film['tillåten_ålder']} år och {textstatus}.")
Det är exakt samma sak som att skriva:
Kodexempel: Vanlig if-sats
if film["textad"]: textstatus = "har undertext" else: textstatus = "har ingen undertext" print(f"{film['titel']} är tillåten från {film['tillåten_ålder']} år och {textstatus}.")
Detta är ett smidigt sätt att skriva kortare kod, men båda varianterna fungerar lika bra. Du kan själv välja vad som känns mest läsbart.
Uppgift: m06u11
Skapa en lista med, minst tre, kurser du läser på skolan som var och en representeras som en dictionary. I denna dictionaryn sparar du namnet på läraren och om det finns en lärobok eller inte i kursen.
Skriv ut en snygg lista med all information.
6.2.4 Nästlade strukturer
I vissa situationer räcker det inte med en enkel dictionary eller en lista av dictionaries. Då kan vi kombinera dem på ännu mer avancerade sätt, t.ex. med listor inuti dictionaries eller dictionaries inuti listor som i sin tur innehåller fler listor. Det här är användbart om du vill organisera till exempel skolklasser med flera elever och varje elev har flera betyg.
Kodexempel: Lista med klasser, där varje klass innehåller en lista med elever
klasser = [ { "klass": "NA22", "elever": [ {"namn": "Alva", "ålder": 17}, {"namn": "Joel", "ålder": 18} ] }, { "klass": "TE22", "elever": [ {"namn": "Sara", "ålder": 17}, {"namn": "Omar", "ålder": 18} ] } ] # Skriv ut alla elever och vilken klass de går i for klass in klasser: for elev in klass["elever"]: print(f"{elev['namn']} går i {klass['klass']}")
Utskrift
Alva går i NA22 Joel går i NA22 Sara går i TE22 Omar går i TE22
Kodexempel: En elev med en lista av provresultat
elev = { "namn": "Alva", "program": "NA", "provresultat": [78, 84, 92] } # Räkna ut medelvärde medel = sum(elev["provresultat"]) / len(elev["provresultat"]) print(f"{elev['namn']} har ett medelvärde på {medel:.1f}")
Utskrift
Alva har ett medelvärde på 84.7
Uppgift: m06u12
Skapa en dictionary för en elev med följande information:
- namn
- ålder
- program
- intressen (lista)
Skapa en struktur som innehåller två klasser. Varje klass ska innehålla minst två elever.
Varje elev ska vara en dictionary med namn, ålder och en lista av betygpoäng (0, 10, 12.5, 15, 17.5 eller 20).
Skriv ut namnet på varje elev, vilken klass hen går i och elevens betygsmedelvärde.
Nu har du testat på olika sätt att strukturera och organisera data i Python. Genom att kombinera listor och dictionaries kan du bygga egna små databaser – helt i kod.
I nästa avsnitt kommer vi att använda dessa strukturer för att göra enklare analyser, t.ex. räkna ut medelvärden, filtrera data och plocka ut det viktigaste.
Uppgift: Projektuppgift, del 1
Under resten av momentet så kommer en liten större uppgift byggas upp steg för steg. Detta är första delen av den uppgiften.
Uppgiften är att bygga upp en struktur för ett klimatdatasystem. Du får data från olika orter: platsnamn, medeltemperatur, nederbörd och datum.
- Strukturera varje mätning som en dictionary
- Samla alla mätningar i en lista
- Spara hela listan som JSON
- Läs in datan från filen och skriv ut en enkel lista med all information. Om du kan så sortera utskriften efter nederbörd i fallande skala. Mest för att bevisa att det i Borås regnar mest.
Du kan bygga vidare på denna uppgift efter varje delmoment eller göra allt i slutet.
6.3 Enkel dataanalys utan bibliotek
I detta avsnitt fokuserar vi på att analysera och bearbeta data med hjälp av ren Python, utan att använda några externa bibliotek som t.ex. pandas eller numpy. Du kommer att lära dig att samla, filtrera, räkna och sammanställa information från listor och dictionaries på ett effektivt sätt.
Det är viktigt att kunna utföra dessa analyser med grunderna i Python innan man lägger till fler verktyg. För dig som senare vill fördjupa dig i dataanalys finns det flera kraftfulla bibliotek att utforska, som t.ex. pandas för datahantering, numpy för avancerad numerisk beräkning och matplotlib för diagram och visualisering. Men i detta moment håller vi oss till det vi kan bygga själva från grunden.
6.3.1 Grundläggande analys (summa, medel, max/min)
I det här avsnittet använder vi inbyggda Python-funktioner för att analysera data: sum()
, len()
, max()
och min()
. Vi räknar ut t.ex. medelvärde, högsta poäng eller antal.
Kodexempel: Enkel lista
resultat = [72, 88, 91, 65, 78] print("Antal resultat:", len(resultat)) print("Högsta poäng:", max(resultat)) print("Lägsta poäng:", min(resultat)) print("Medelpoäng:", sum(resultat)/len(resultat))
Utskrift
Antal resultat: 5 Högsta poäng: 91 Lägsta poäng: 65 Medelpoäng: 78.8
Kodexempel: Lista med dictionaries
elever = [ {"namn": "Alva", "resultat": [65, 72, 88]}, {"namn": "Elias", "resultat": [78, 91]}, {"namn": "Sara", "resultat": [84]} ] alla_resultat = [] for elev in elever: alla_resultat += elev["resultat"] print("Totalt antal resultat:", len(alla_resultat)) print("Högsta poäng:", max(alla_resultat)) print("Lägsta poäng:", min(alla_resultat)) print("Medelpoäng:", round(sum(alla_resultat)/len(alla_resultat), 2))
Utskrift
Totalt antal resultat: 6 Högsta poäng: 91 Lägsta poäng: 65 Medelpoäng: 79.67
Uppgift: m06u13
Du har en lista med elever och deras resultat:
Lista med elever och resultat
elever = [ {"namn": "Anna", "poäng": [5, 7, 6]}, {"namn": "Nils", "poäng": [8, 6]}, {"namn": "Lea", "poäng": [9]} ]
- Skapa en gemensam lista med alla poäng
- Räkna ut totalt antal, medel, max och min
6.3.2 Filtrera och analysera delar av data
Vi vill ofta analysera en delmängd av datan, t.ex. bara värden som är över ett visst gränsvärde. Här visar vi först hur du kan filtrera en enkel lista, och därefter hur du kan jobba med mer komplex data där varje objekt innehåller en egen lista av värden.
Kodexempel: Filtrera i lista
poäng = [4, 8, 6, 10, 3] filtrerade = [p for p in poäng if p > 5] print("Poäng över 5:", filtrerade)
Utskrift
Poäng över 5: [8, 6, 10]
Inom mer avancerade datamodeller har vi ofta listor med dictionaries där en nyckel pekar på en lista av värden. Då behöver vi iterera både över objekten och över listorna i varje objekt.
Kodexempel: Filtrera i lista av dictionaries (med lista som värde)
def filtrera_höga(elev): return [v for v in elev["resultat"] if v >= 7] elever = [ {"namn": "Anna", "resultat": [5, 7, 6]}, {"namn": "Nils", "resultat": [4, 3]}, {"namn": "Lea", "resultat": [9, 10]} ] for elev in elever: print(elev["namn"], ":", filtrera_höga(elev))
Utskrift
Anna : [7] Nils : [] Lea : [9, 10]
Det är ofta en fördel att ha en funktion för att kunna tillämpa filtret på ny data senare, istället för att lagra resultatet som ny nyckel.
Uppgift: m06u14
Du har en lista med elever och deras resultat:
Kodexempel:
elever = [ {"namn": "Ida", "poäng": [3, 7, 8]}, {"namn": "Leo", "poäng": [5, 4]}, {"namn": "Zara", "poäng": [9, 6]} ]
- Skriv en funktion som filtrerar ut alla poäng mellan 5 och 8. 5 och 8 skall finnas kvar efter filtreringen.
- Använd funktionen på varje elev
6.3.3 Gruppering och räknare
Om vi har data med kategorier (t.ex. elevernas program eller ämnesval) kan vi gruppera dem och räkna hur många som tillhör varje grupp. Det finns flera sätt att bygga upp en sådan summering.
När man bygger upp en räknare i en dictionary behöver man kontrollera om nyckeln redan finns. Det kan göras på två sätt:
- Med if/else: Kontrollera om nyckeln finns innan man ökar värdet.
- Med
.get()
: Hämtar värdet om det finns, annars returneras ett standardvärde (t.ex. 0).
.get()
är ett smidigt sätt att undvika KeyError
när man bygger upp en ny dictionary steg för steg.
Kodexempel: Gruppering och räknare, två metoder
elever = [ {"namn": "Alva", "favoritämnen": ["Kemi", "Biologi"]}, {"namn": "Elias", "favoritämnen": ["Fysik"]}, {"namn": "Sara", "favoritämnen": ["Kemi"]}, {"namn": "Lina", "favoritämnen": ["Biologi", "Kemi"]} ] # Variant 1: med if/else antal1 = {} for elev in elever: for ämne in elev["favoritämnen"]: if ämne in antal1: antal1[ämne] += 1 else: antal1[ämne] = 1 # Variant 2: med .get() antal2 = {} for elev in elever: for ämne in elev["favoritämnen"]: antal2[ämne] = antal2.get(ämne, 0) + 1 # .get() returnerar 0 om nyckeln saknas print("Med if/else:", antal1) print("Med get():", antal2)
Utskrift
Med if/else: {'Kemi': 3, 'Biologi': 2, 'Fysik': 1} Med get(): {'Kemi': 3, 'Biologi': 2, 'Fysik': 1}
Båda metoder ger samma resultat, men .get()
kan vara lite smidigare att skriva.
En sådan sammanställning passar utmärkt för att senare visualisera med matplotlib
.
Uppgift: m06u15
Du har en lista med personer och deras språk de talar:
Lista med talade språk
personer = [ {"namn": "A", "språk": ["svenska", "engelska"]}, {"namn": "B", "språk": ["engelska"]}, {"namn": "C", "språk": ["svenska", "tyska"]}, {"namn": "D", "språk": ["engelska", "tyska"]} ]
Skapa en dictionary med antal personer som talar varje språk. Sortera gärna utskriften med de mest talade språken först.
Använd gärna både if/else och .get()
och jämför
Uppgift: Projektuppgift, del 2
I denna del ska du fortsätta arbeta med den datafil som du jobbade med i del 1. Målet är att bearbeta datan till ett format som passar för att skapa diagram i nästa moment.
Här kommer en lämplig struktur på json-filen som enkelt kan läsas in som en dictionary i python och sedan arbetas vidare med.
klimatdata.json
[ {"plats": "Göteborg", "temp": 13.6, "nederbörd": 4.1, "datum": "2024-09-01"}, {"plats": "Borås", "temp": 17.8, "nederbörd": 2.9, "datum": "2024-09-01"}, {"plats": "Alingsås", "temp": 22.9, "nederbörd": 1.0, "datum": "2024-09-01"} // ... fler rader enligt tidigare struktur ]
Uppgiften i denna del är att sammanställa data och förbereda för att i nästa del skapa utskrifter av bearbetat data och även rita upp diagram.
- Läs in json-filen eller se till att din datastruktur är lik filens struktur.
- Gruppera temperaturen per plats och räkna ut medeltemperatur per plats.
- Gör samma sak för nederbörd – d.v.s. beräkna medelnederbörd per plats.
- Spara de färdiga resultaten i två dictionaries:
medel_temp = {"Göteborg": 17.1, "Borås": 19.2, ...}
medel_nederbörd = {"Göteborg": 3.5, "Borås": 5.2, ...}
Du kan bygga vidare på denna uppgift efter varje delmoment eller göra allt i slutet.
6.4 Visualisering med matplotlib
I detta avsnitt lär du dig att skapa enkla diagram i Python med hjälp av matplotlib.pyplot. Vi använder inga externa dataverktyg som pandas – endast grundläggande Python och listor/dictionaries.
Du får lära dig att skapa tre vanliga typer av diagram:
- Stapeldiagram – för att visa jämförelser mellan kategorier
- Linjediagram – för att visa förändring över tid
- Cirkeldiagram – för att visa fördelningar
Vi går också igenom hur du kan formatera diagrammen på olika sätt.
6.4.1 Stapeldiagram – jämförelser mellan grupper
För att kunna använda matplotlib.pyplot
måste du först installera paketet matplotlib. Det gör du på ett av följande sätt:
- I Windows: skriv
pip install matplotlib
i terminalen (kommandoprompt eller i PyCharm) - På Mac: använd
pip3 install matplotlib
eller lägg till via "Python Packages" i PyCharm
När du installerat klart kan du importera biblioteket och börja rita diagram. Antag att vi har data om hur många elever som valt olika språk:
Kodexempel: Enkelt stapeldiagram
import matplotlib.pyplot as plt # Importerar ritverktyget pyplot från matplotlib språk = ["Franska", "Spanska", "Tyska"] antal = [12, 18, 7] plt.bar(språk, antal) # Skapar ett stapeldiagram där x = språk (etiketter), y = antal (höjd på staplar) plt.title("Val av språk") # Lägger till en rubrik plt.xlabel("Språk") # Etikett under x-axeln plt.ylabel("Antal elever") # Etikett vid y-axeln plt.show() # Visar diagrammet i ett nytt fönster
Diagram

Det här diagrammet visar ett enkelt stapeldiagram där varje stapel representerar antalet elever per språkval.
Meddelanden vid körning på Mac
När du kör Python-program på Mac, särskilt sådana som ritar diagram eller öppnar grafiska fönster (t.ex. med matplotlib
), kan det hända att du ser meddelanden som dessa i terminalen:
Kodexempel:
2025-04-28 10:56:08.346 Python[4043:7849391] +[IMKClient subclass]: chose IMKClient_Modern 2025-04-28 10:56:08.346 Python[4043:7849391] +[IMKInputSession subclass]: chose IMKInputSession_Modern
Detta är helt normalt och betyder att macOS väljer en modern hantering av tangentbordsinmatning (IMK står för Input Method Kit) för det grafiska fönstret som öppnas. Det påverkar inte ditt program på något sätt och kan ignoreras.
6.4.1.1 Anpassning av stapeldiagram
Nu när vi vet hur man bygger grundläggande stapeldiagram kan vi också förfina dem med färger, etiketter och tydligare staplar.
Kodexempel:
plt.bar(språk, antal, color=["red", "green", "blue"]) # Välj färger för varje stapel plt.yticks(range(0, 21, 5)) # Visa bara hela femtal på y-axeln
Diagram

Vill du ha liggande staplar istället för stående, använd barh()
i stället för bar()
:
Kodexempel:
plt.barh(språk, antal, color=["red", "green", "blue"]) # Välj färger för varje stapel plt.xticks(range(0, 21, 5)) # Visa bara hela femtal på x-axeln
Diagram

Det går också att visa exakta värden på varje stapel.
Kodexempel:
for i in range(len(språk)): plt.text(språk[i], antal[i] + 0.5, str(antal[i]), ha="center") # Text ovanför varje stapel
Diagram

Justera bredd och kantlinjer går också
Kodexempel:
plt.bar(språk, antal, color="green", width=0.6, edgecolor="black") # Smalare staplar med grön färg och svart kant
Diagram

Uppgift: m06u17
Skapa ett stapeldiagram som visar befolkningen i fem kommuner:
- Skapa ett stående stapeldiagram
- Använd olika färger för staplarna
- Rotera x-etiketterna 30 grader
- Visa värden ovanför varje stapel
- Lägg till titel och axelrubriker
Tips: Funktionen plt.xticks(rotation=45)
används för att rotera etiketterna på x-axeln så att de inte krockar eller blir svårlästa.
Data
kommuner = ["Göteborg", "Borås", "Alingsås", "Lerum", "Kungsbacka"] befolkning = [587000, 113000, 43000, 43000, 85000]
Stapeldiagram passar bra för jämförelser mellan kategorier. Men om vi istället vill visa utveckling över tid är linjediagram ett bättre val.
6.4.2 Linjediagram
Här visar vi hur antalet elever som valt programmering har förändrats över fyra läsår.
Kodexempel: Linjediagram
import matplotlib.pyplot as plt år = ["2020", "2021", "2022", "2023"] # Värden för x-axeln (tidslinje) antal = [14, 18, 21, 25] # Värden för y-axeln (antal elever) plt.plot(år, antal, marker="o") # Skapar ett linjediagram med markeringar vid varje punkt plt.title("Elever som valt Programmering") # Rubrik för diagrammet plt.xlabel("År") # Etikett under x-axeln plt.ylabel("Antal elever") plt.grid(True) # Visar både horisontella och vertikala hjälplinjer plt.show()
Vill du bara visa linjer på en axel?
Kodexempel:
plt.grid(axis="y") # Endast horisontella linjer plt.grid(axis="x") # Endast vertikala linjer
Detta kan ge ett renare utseende i vissa diagram.
Diagram

Linjediagram passar bra när du vill visa trender eller utveckling över tid.
6.4.2.1 Färg och linjestil
Kodexempel:
plt.plot(år, antal, color="green", linestyle="--", marker="o") # Streckad grön linje med cirkelmarkörer
Diagram

6.4.2.2 Flera linjer i samma diagram
Kodexempel:
år = ["2020", "2021", "2022", "2023"] prog = [14, 18, 21, 25] webb = [10, 15, 17, 22] plt.plot(år, prog, label="Programmering", color="blue", marker="o") plt.plot(år, webb, label="Webbutveckling", color="orange", marker="s") plt.legend() # Visa etikettförklaring
Diagram

6.4.2.3 Visa exakta värden vid varje punkt
Kodexempel:
for i in range(len(år)): plt.text(år[i], antal[i] + 0.5, str(antal[i]), ha="center")
Diagram

Dessa små förbättringar kan göra linjediagrammet både snyggare och lättare att tolka.
Uppgift: m06u18
Skapa ett linjediagram som visar hur många elever som deltagit i skolans teknikklubb under de senaste fem åren:
Kodexempel:
år = ["2019", "2020", "2021", "2022", "2023"] deltagare = [8, 12, 10, 15, 18]
Uppgiften är att du skall:
- Rita ett linjediagram där punkterna markeras med cirklar
- Lägg till titel och axelrubriker
- Använd valfri färg på linjen
- Visa varje värde ovanför respektive punkt
- Aktivera rutnät (grid)
6.4.3 Cirkeldiagram
Om du vill visa andelar av en helhet passar ett cirkeldiagram bra:
Kodexempel:
import matplotlib.pyplot as plt ämnen = ["Biologi", "Kemi", "Fysik"] # Etiketter för varje tårtbit andelar = [25, 30, 45] # Storlek (andel) för varje kategori plt.pie(andelar, labels=ämnen, autopct="%1.0f%%") # Skapar cirkeldiagram med etiketter och procent plt.title("Fördelning av favoritämnen") # Rubrik för cirkeldiagrammet plt.show()
Diagram

Varje sektor visar andelen elever som valt respektive ämne.
Tänk på att cirkeldiagram fungerar bäst med några få tydliga kategorier. Om du har många värden eller stora skillnader kan staplar vara tydligare.
6.4.4 Kombinerade diagram – staplar och linjer i samma figur
Ibland kan vi vilja visa flera datatyper samtidigt, t.ex. jämföra aktuella värden och en trend. Då kan vi kombinera flera diagramformer i samma bild.
6.4.4.1 Grupperade staplar – flera serier i samma diagram
När du vill visa flera jämförelsepunkter för varje kategori, t.ex. antal elever i olika kurser över tre år, kan du använda grupperade staplar:
Kodexempel:
kurser = ["Programmering", "Webbutveckling", "Matematik"] # Lista med kurser år_2021 = [15, 10, 20] # Antal elever år 2021 år_2022 = [17, 13, 19] # Antal elever år 2022 år_2023 = [20, 15, 22] # Antal elever år 2023 x_pos = list(range(len(kurser))) # Skapar en lista med positioner 0, 1, 2 för kurserna bredd = 0.25 # Bredd på varje stapel # Justera positioner för staplarna så att de hamnar bredvid varandra x1 = [x - bredd for x in x_pos] # Flytta första stapeln åt vänster x2 = x_pos # Andra stapeln i mitten x3 = [x + bredd for x in x_pos] # Flytta tredje stapeln åt höger # Rita staplar för varje år plt.bar(x1, år_2021, width=bredd, label="2021") plt.bar(x2, år_2022, width=bredd, label="2022") plt.bar(x3, år_2023, width=bredd, label="2023") # Lägg till etiketter och titel plt.xticks(x_pos, kurser) plt.xlabel("Kurs") plt.ylabel("Antal elever") plt.title("Antal elever per kurs och år") plt.legend() plt.tight_layout() plt.show()
Diagram

Det här ger ett tydligt diagram där du kan jämföra flera år sida vid sida för varje kurs.
Förutom att visa flera stapelgrupper kan du även kombinera olika typer av diagram i en och samma figur. Det är särskilt användbart om du vill visa både aktuella värden och en jämförelse eller trend på samma gång. Här är ett exempel där vi visar antalet elever i två ämnen: ett med stapeldiagram och ett med linjediagram.
Kodexempel:
import matplotlib.pyplot as plt ämnen = ["Fysik", "Kemi", "Biologi", "Teknik"] antal = [12, 15, 9, 11] utveckling = [10, 13, 8, 12] # För att visa en trend med linje plt.bar(ämnen, antal, label="Nuvarande") plt.plot(ämnen, utveckling, color="red", marker="o", label="Utveckling") plt.title("Elever per ämne och utveckling") plt.xlabel("Ämne") plt.ylabel("Antal elever") plt.legend() plt.show()
Diagram

Detta kan vara användbart när du vill visa både aktuella värden och en jämförelse eller trend i samma bild.
6.4.4.2 Kombinerat med två y-axlar
Om dina dataserier har olika enheter eller skala – t.ex. poäng och tid – kan du använda två y-axlar:
Kodexempel:
import matplotlib.pyplot as plt # Importera ritverktyget ämnen = ["Fysik", "Kemi", "Biologi", "Teknik"] # Lista med ämnen betyg = [3.1, 3.5, 3.2, 3.0] # Lista med medelbetyg (skalor t.ex. 1-5) antal = [20, 25, 18, 22] # Lista med antal elever fig, ax1 = plt.subplots() # Skapa en figur och en första axel (ax1) # Stapeldiagram på första y-axeln ax1.bar(ämnen, antal, color="lightblue", label="Antal elever") ax1.set_ylabel("Antal elever", color="lightblue") # Etikett till vänster (y-axel 1) ax1.tick_params(axis="y", labelcolor="lightblue") # Färgsätt y-etiketter så de matchar staplarna # Skapa en andra y-axel som delar x-axeln ax2 = ax1.twinx() # Linjediagram på andra y-axeln ax2.plot(ämnen, betyg, color="darkgreen", marker="o", label="Medelbetyg") ax2.set_ylabel("Medelbetyg", color="darkgreen") # Etikett till höger (y-axel 2) ax2.tick_params(axis="y", labelcolor="darkgreen") # Färgsätt y-etiketter så de matchar linjen # Lägg till en titel och fixa layout plt.title("Antal elever och medelbetyg per ämne") fig.tight_layout() # Justera layout så allt får plats plt.show()
Diagram

Detta gör det enkelt att läsa av både värden och trender – även om de tillhör olika skalor.
Här kommer några praktiska förbättringar du kan göra:
Kodexempel:
plt.xticks(rotation=20) # Rotera etiketter om de krockar plt.tight_layout() # Justera automatiskt layout plt.savefig("diagram.png") # Spara till bildfil
Svenska tecken fungerar ofta bra, men om de ser konstiga ut kan du testa att spara filen som UTF-8 encodings='utf-8'
och använda ett typsnitt som stödjer ÅÄÖ.
6.4.4.3 Styra skalan på y-axlarna
Om du vill sätta egen gräns för y-axeln – till exempel om du vill tvinga staplarna att börja på 0 och sluta på 10 – kan du använda följande metoder
Kodexempel:
ax1.set_ylim(0, 10) # För stapeldiagrammets axel ax2.set_ylim(-5, 25) # För linjediagrammets axel
Detta används när du skapat egna axlar (som ax1
, ax2
) och vill styra varje y-axel exakt. Om du endast använder en y-axel och inte har skapat den tidigare så kan du istället skriva följande kod:
Kodexempel:
plt.ylim(0, 10)
Om du vill få mer inspiration om vad du kan göra med matplotlib
så kolla på denna cheat sheet som kan vara användbar. Även om det är ont om fullständiga exempel så kan vissa attribut användas direkt medan andra mer komplicerade saker kan användas för att söka sig vidare efter information.
Uppgift: Projektuppgift, del 3
Omvandla dictionary till listorInnan du ritar ett diagram behöver du omvandla dina dictionaries till listor – men kontrollera att platserna finns i samma ordning i båda dictionaries. Dictionaries är i nyare versioner av Python oftast ordnade, men det är inte garanterat om de har olika ursprung.
För att vara säker kan du iterera över platserna i en gemensam lista:
Dina data är sparade som dictionaries, t.ex.:
Kodexempel:
medel_temp = {"Göteborg": 16.7, "Borås": 19.3, "Alingsås": 18.6, "Lerum": 16.5, "Kungsbacka": 15.5} medel_nederbörd = {"Göteborg": 3.0, "Borås": 3.4, "Alingsås": 4.1, "Lerum": 5.6, "Kungsbacka": 4.0}
För att skapa diagram behöver du två listor – en med platser och en med värden. Du kan enkelt omvandla dina dictionaries så här:
Kodexempel:
platser = list(medel_temp.keys()) temp = [medel_temp[plats] for plats in platser] nederbörd = [medel_nederbörd[plats] for plats in platser]
Dessa listor kan du sedan använda i dina diagram. Du har tidigare i momentet bearbetat klimatdata till två dictionaries:
medel_temp
- medeltemperatur per platsmedel_nederbörd
- medelnederbörd per plats
I denna uppgift ska du visualisera båda dessa med hjälp av matplotlib. Du väljer själv om du vill skapa:
- två separata diagram (ett för temperatur och ett för nederbörd)
- ett kombinerat diagram med två y-axlar
Så här skulle ett kombinerat diagram kunna se ut:
Diagram

- Se till att axlarna är tydliga och korrekt färgkodade.
- Använd
tight_layout()
så att inget klipps bort. - Vill du visa två separata diagram? Använd två
plt.figure()
eller kör koden två gånger med olika figurer.
6.5 Läsning och lagring av data i CSV-filer
I detta avsnitt kommer du att lära dig hur du arbetar med CSV-filer i Python på ett grundläggande och praktiskt sätt. Du kommer att få läsa in data från en CSV-fil, bearbeta informationen med hjälp av listor och dictionaries samt spara bearbetat data tillbaka till en ny CSV-fil. Dessutom får du lära dig hur du öppnar och exporterar filer med Google Sheets eller Excel.
Vi använder endast inbyggda Python-moduler, vilket betyder att du inte behöver installera några extra bibliotek för att kunna genomföra momenten.
6.5.1 Vad är en CSV-fil?
En CSV-fil (Comma-Separated Values) är en enkel textfil där varje rad representerar en post och varje värde separeras med till exempel kommatecken eller semikolon. CSV används för att spara tabellformad data och kan enkelt öppnas i program som Google Sheets, Excel eller läsas direkt i Python.
Exempel på innehåll i en CSV-fil
klass,namn,poäng TE21,Alva,85 TE21,Leo,73 NA22,Maja,91 NA22,Elias,88
Observera: I Sverige används ibland semikolon (;) istället för kommatecken på grund av decimalformatering. Modulen csv
är inbyggd i Python – du behöver inte installera något extra.
6.5.2 Läsa från CSV-fil i Python
Vi använder modulen csv
och verktyget pprint
för att läsa och skriva ut datan på ett lättläst sätt.
Kodexempel: Läs in en CSV-fil
import csv from pprint import pprint # Importera pretty print för snyggare utskrift with open("resultat.csv", encoding="utf-8") as fil: reader = csv.DictReader(fil, delimiter=",") # Skapa en reader-objekt (välj ";" om din fil använder semikolon) data = list(reader) # Läs in alla rader som en lista av dictionaries pprint(data) # Snygg och lättläst utskrift av listan
Utskrift
[ {"klass": "TE21", "namn": "Alva", "poäng": "85"}, {"klass": "TE21", "namn": "Leo", "poäng": "73"}, {"klass": "NA22", "namn": "Maja", "poäng": "91"}, {"klass": "NA22", "namn": "Elias", "poäng": "88"} ]
Alla värden läses som strängar. Om du behöver göra beräkningar på t.ex. poäng måste du konvertera dem till heltal (int
). För att konvertera fältet "poäng" från sträng till heltal i hela listan kan du använda en for
-loop:
Kodexempel: Konvertera poäng till int
for elev in data: elev["poäng"] = int(elev["poäng"])
Nu kan du göra uträkningar som medelvärde, högsta och lägsta poäng direkt på heltal istället för strängar.
Modulen pprint
(pretty print) används för att skriva ut komplexa datastrukturer på ett snyggt och lättläst sätt. Du kan också anpassa hur datan skrivs ut, t.ex. genom att styra radbrytning och indrag.
Kodexempel: Användning av pprint
pprint(data, width=60) # Begränsar radens längd för ännu snyggare layout pprint(data, indent=4) # Lägger till extra indrag för bättre läsbarhet
Det kan vara extra hjälpsamt om listorna är stora eller innehåller mycket information.
Uppgift: m06u19
Läs in en CSV-fil med 200 provresultat från 5 olika klasser.
- Beräkna medelpoäng, högsta och lägsta poäng per klass.
- Konvertera "poäng" till heltal innan beräkningarna.
- Skriv ut resultatet på skärmen med snygg formatering.
Ladda ner filen m06u19_data.csv.
6.5.3 Skriva till CSV-fil i Python
Efter att ha bearbetat datan kan du skriva resultatet till en ny CSV-fil. Vi använder modulen csv
och klassen DictWriter
för att skriva en lista av dictionaries till en fil.
Kodexempel: Spara sammanfattning till CSV
import csv # Skapa en lista med sammanfattningsdata sammanfattning = [ {"klass": "TE21", "medel": 79, "högst": 85, "lägst": 73}, {"klass": "NA22", "medel": 89, "högst": 91, "lägst": 88} ] # Öppna en ny fil för skrivning with open("sammanfattning.csv", mode="w", newline="", encoding="utf-8") as fil: writer = csv.DictWriter(fil, fieldnames=["klass", "medel", "högst", "lägst"]) # Skapa ett skriv-objekt och ange kolumner writer.writeheader() # Skriv ut rubrikraden i filen writer.writerows(sammanfattning) # Skriv ut alla dictionaries som rader i filen
Förklaring till koden
DictWriter
skapar ett skriv-objekt där vi bestämmer ordningen på kolumnerna (fieldnames
).writeheader()
skriver rubrikraden i filen.writerows()
skriver varje dictionary som en rad i CSV-filen.newline=""
förhindrar extra tomrader i filen (särskilt viktigt på Windows).encoding="utf-8"
ser till att svenska tecken som å, ä och ö fungerar korrekt.
Kolumnordningen i fieldnames
styr hur datan sparas. Dubbelkolla alltid att alla dictionaries i listan har samma nycklar som fieldnames
, annars får du fel.
Resultat i filen sammanfattning.csv
klass,medel,högst,lägst TE21,79,85,73 NA22,89,91,88
Uppgift: m06u20
Spara en sammanfattning av resultaten från uppgift m06u19 till en ny CSV-fil med rubrikrad. Sammanställningen ska visa medelpoäng, högsta och lägsta poäng för varje klass.
Obs: Börja med att läsa in filen resultat.csv från uppgift m06u19 om du inte redan har datan i minnet.
- Använd rubrikrad mha
writeheader()
. - Spara filen som "sammanfattning.csv".
- Öppna filen i Google Sheets enligt instruktionen nedan och kontrollera formatet.
6.5.4 Arbeta med CSV i Google Sheets och Excel
När du har sparat en CSV-fil är det enkelt att öppna den i Google Sheets eller Excel för att kontrollera att datan ser korrekt ut.
6.5.4.1 Öppna en CSV-fil i Google Sheets
Öppna en CSV-fil i Google Sheets
- Gå till Google Drive
- Klicka på "+ Ny" -> "Filuppladdning".
- Välj din sparade CSV-fil och ladda upp den.
- Högerklicka på filen -> välj "Öppna med" -> "Google Kalkylark".
Filen öppnas nu som ett kalkylark där varje kolumn motsvarar ett fält från CSV-filen.
6.5.4.2 Vanliga problem och lösningar
Problem: All data hamnar i en enda kolumn.
Orsak: Google Sheets kan ha missförstått vilken avgränsare som används (komma eller semikolon).
Lösning:
- Skapa ett nytt tomt kalkylark.
- Gå till Arkiv -> Importera -> Ladda upp din CSV-fil.
- I importinställningarna välj rätt avgränsare:
- Komma om filen använder kommatecken.
- Semikolon om filen använder semikolon.
Tips: Python sparar som standard med komma som avgränsare om du inte angett något annat.
6.5.4.3 Varning vid redigering och export
Om du redigerar en CSV-fil i Google Sheets och vill spara om den:
- Gå till Arkiv → Ladda ner → Kommaavgränsad CSV (.csv, aktuellt blad).
- Se till att du sparar endast det aktuella bladet.
- Var försiktig med ändringar av talformat och datumformat – det kan påverka hur filen läses tillbaka i Python.
6.5.4.4 Exportera från Google Sheets till CSV
Om du fått en färdig fil i Google Sheets (t.ex. från projektuppgiften) och vill använda den i Python:
- Öppna kalkylarket i Google Sheets.
- Klicka på Arkiv -> Ladda ner -> Kommaavgränsad CSV (.csv, aktuellt blad).
- Filen sparas som en vanlig CSV-fil som kan läsas in i Python med
csv.DictReader
.
Uppgift: Projektuppgift, del 4
I denna projektuppgift arbetar du vidare med ett större dataset från ett klimatprojekt.
Du får tillgång till en CSV-fil som innehåller dagliga mätningar från åtta orter i Västra Götaland under januari till mars.
Överblick – Det här ska du göra
- Läsa in klimatdata från en CSV-fil.
- Bearbeta datan: räkna ut medelvärden och hitta extremvärden.
- Skapa flera olika typer av diagram.
- Spara en sammanfattning till en ny CSV-fil.
- Kontrollera resultatet i Google Sheets.
Datafilen heter "klimatdata_jan_mars.csv" och innehåller:
- plats, ortens namn
- datum, i formatet ÅÅÅÅ-MM-DD
- temp, medeltemperatur i grader Celsius (kan vara negativ)
- nederbörd, i millimeter
Totalt innehåller filen cirka 700 mätvärden.
Steg-för-steg-instruktion
- Läs in datan
- Använd
csv.DictReader för att läsa in filen.
- Konvertera "temp" och "nederbörd" till float så att du kan räkna med värdena.
- Bearbeta datan
- Beräkna medeltemperatur per ort.
- Beräkna medelnederbörd per ort.
- Hitta högsta och lägsta temperatur per ort.
- Filtrera ut alla dagar där nederbörden var större än 10 mm.
- Tips: använd dictionaries för att samla information per ort.
- Skapa diagram
- Stapeldiagram över medeltemperatur per ort.
- Stapeldiagram över medelnederbörd per ort.
- Kombinerat diagram:
- Nederbörd som staplar.
- Temperatur som linje med punkter.
- Använd två separata y-axlar (
twinx()
) - Spara en sammanfattning till CSV
- Skapa en ny lista av dictionaries där varje rad innehåller:
- Ortens namn
- Medeltemperatur
- Medelnederbörd
- Högsta temperatur
- Lägsta temperatur
- Använd
csv.DictWriter
för att skriva till en ny fil, t.ex. "sammanfattning_klimat.csv". - Kontrollera resultatet
- Öppna din sparade CSV-fil i Google Sheets.
- Kontrollera att alla rubriker och värden ligger rätt.
Glöm inte att använda tight_layout()
för snyggare diagram.
Tips och påminnelser
- Arbeta strukturerat: använd gärna funktioner för att hålla koden tydlig.
- Skriv ut mellanresultat för att kontrollera att allt fungerar innan du bygger vidare.
- Var noga med filkodning (encoding="utf-8") och avgränsare om du öppnar filen i Google Sheets.
- Se till att diagrammen får tydliga rubriker och etiketter på axlarna.
Datafilen klimatdata_jan_mars.csv.
Tips för snyggare diagram
För att undvika att ortnamn överlappar eller skärs av, använd följande:
plt.xticks(rotation=30)
för att rotera x-axelns etiketter om ortsnamnen överlappar eller skärs av.plt.grid(axis="y")
för att lägga till horisontella hjälplinjer.plt.tight_layout()
för att justera marginalerna automatiskt.figsize=(10, 6)
om du vill göra bilden större.
När du är klar med uppgiften så säg gärna till läraren och visa upp din lösning.