Tak, mogą się znudzić. Tak, dobrze jest mieć wiele narzędzi w swoim zestawie narzędzi (oczywiście). Jednakżejeśli Państwa wykres słupkowy “nie daje rady” lub czują Państwo, że jest “nadużywany”, proszę nie winić narzędzia, proszę winić pracownika (tj. siebie).

Istnieje wiele powodów, dla których mogą Państwo poczuć, że po prostu nie są w stanie stworzyć kolejnego wykresu słupkowego.

  • Państwa pulpit nawigacyjny ma zbyt wiele widżetów
  • Państwa prezentacja ma zbyt wiele slajdów
  • Niektóre z Pana wizualizacji powinny być czymś innym
  • Wykresy słupkowe, których Pan użył to nudne proszę spojrzeć

Proszę zawsze pamiętać o pierwszych 3 punktach, ale ostatni jest bardzo ważny. Być może powodem, dla którego następny wykres słupkowy wydaje się o jeden za dużo, jest to, że wszystkie poprzednie mają ten sam wygląd. nudne osie, to samo nudne linie siatki, to samo nudne tytuły i to samo nudne pusta przestrzeń. Myślał Pan kiedyś o tym? Być może ma Pan związane ręce, ponieważ jest to pulpit nawigacyjny, a ciekawe tytuły i adnotacje nie są możliwe. Ale jeśli budują Państwo talię, nie ma wymówek.

Teraz chcę być jasny, nie mówię, że wszystko, co może być wykresem słupkowym powinien być wykresem słupkowym. Proszę po prostu nie obwiniać wykresu słupkowego za jego wszechstronność i nauczyć się z niego korzystać.

Dane

Gusta zmieniają się wraz z wiekiem. Być może był Pan typowym amerykańskim studentem i lubił Pan pić kiepskie piwo w wieku 20 lat, a potem stał się Pan snobem pijącym tylko IPA. Może w końcu zainteresował się Pan winem, albo pomyślał Pan, że jest fancy, więc zaczął Pan pić whiskey z lodem (ale na początku była to whiskey Jack Daniels 😆, więc może fancy klasy średniej). Tak, rzeczywiście opisuję siebie.

Jestem teraz po trzydziestce i uwielbiam świetne koktajle. Ile razy byli Państwo na kolacji lub w barze i mieli ochotę na koktajl, ale nie mieli pojęcia, co zamówić, więc panicznie zamawiali wódkę sodową z cytryną / limonką? Mówi Pan wszystkim, że lubi ten napój, ale okłamuje Pan ich, a co ważniejsze, samego siebie.

Więc w wolnym czasie postanowiłem sprawdzić, czy mogę zeskrobać kilka stron internetowych i zebrać kilka przepisów, aby stworzyć przeszukiwalną bazę danych do własnego użytku. Tak, jestem 🤓. Udało mi się zeskrobać 650(!) przepisów z liquor.com. Poniżej znajdą Państwo w pełni oczyszczoną strukturę:

Z liquor.com otrzymałem:

  • recipe_name
  • ingredient
  • unit
  • quantity

Dodałem ręcznie:

  • Wszystkie identyfikatory
  • mapped_ingredient
  • alcohol_type

mapped_ingredient oraz alcohol_type są tutaj ważnymi atrybutami. Jeśli przepis mówi “kawałki limonki“, inny mówi “limonkowe koła“, a inny “limonki, świeżo wyciśnięte“, to wszystkie z nich wymagają wapno. Podobnie jak w przypadku alkoholu – jeśli przepis wymaga “Bombay Sapphire dry gin“, a następnie mapped_ingredient to “wytrawny gin“, ale alcohol_type to po prostu “gin“.

Bezwstydna wtyczka

W rzeczywistości poszedłem o krok dalej i zbudowałem aplikację dash z funkcją logowania, możliwością tworzenia własnego paska, wyszukiwania/ulubienia/zaznaczania przepisów, a także oceniania ich. Proszę pamiętać, że zbudowałem to do obsługi jednego użytkownika, więc wydajność jest w porządku, a baza danych jest na darmowej warstwie Postgres RDS. Ładowanie wszystkich przepisów zajmuje solidne 5-10 sekund, poprawię wydajność aplikacji, gdy będę miał okazję.

Nie ma zbyt wielu szkoleń dotyczących produktu, ale jestem pewien, że każdy z Państwa może dowiedzieć się, jak z niego korzystać.

Wykres słupkowy

Jedną z rzeczy, których nie wiedziałem, gdy chciałem zrobić kilka drinków w domu, było to, co powinienem kupić. Kupując przypadkowe rzeczy ze sklepu monopolowego naraz, wyda Pan o wiele za dużo pieniędzy. Odpowiemy więc na proste pytanie, “W co powinienem zaopatrzyć swój bar, aby móc przygotować jak najwięcej drinków?”.

Kod do tworzenia wykresu słupkowego jest bardzo prosty. Potrzebna jest kategoria xi potrzebują Państwo wartości y. Będziemy używać mapped_ingredient jako kategorii i uzyskamy liczbę unikalnych koktajli dla każdej z nich.

mapped_group = df.loc[
pd.isnull(df["alcohol_type"]), :
].groupby("mapped_ingredient").agg({
"cocktail_id": "nunique"
}).reset_index().sort_values("cocktail_id", ascending=False).head(25)

fig = go.Figure()
fig.add_trace(
go.Bar(
x=mapped_group["mapped_ingredient"],
y=mapped_group["cocktail_id"]
)
)

Proszę zwrócić uwagę na kilka rzeczy:

  • Chcę bezalkoholowe składniki, dlatego odfiltrowuję alkohol.
  • Patrzę tylko na 25 najlepszych. W pewnym momencie nie musi Pan pokazywać więcej słupków. Jeśli pozostałe kategorie są dla Pana ważne, proszę rozważyć umieszczenie ich w kategorii “inne”.

Jeśli czytali Państwo moje poprzednie artykuły, to oczywiście jeszcze nie koniec. Lubimy ładne wykresy. Zanim jednak zaczniemy stylizować, spójrzmy na rzeczywiste dane, ponieważ jest tu kilka interesujących rzeczy do zobaczenia:

  1. Cytryny i limonki dominują
  2. Syrop cukrowy to pozycja obowiązkowa
  3. Jakaś wersja generycznych bittersów przejdzie długą drogę
  4. Mięta jest najczęściej używanym ziołem
  5. Jajko jest O WIELE wyżej niż bym się spodziewał

Ostatnią rzeczą, na którą chciałbym zwrócić uwagę, jest to, że na tym wykresie mamy soki i owoce, z których pochodzą osobno. Kiedy tworzyłem mapowanie, zrobiłem to celowo. Jeśli mają Państwo butelkę soku z limonki, niekoniecznie musi to być limonka. Mogą Państwo potrzebować skórki lub kawałka limonki do dekoracji itp. Jednak w tym ćwiczeniu uważam, że sensowne jest przekształcenie soku z limonki w limonkę, a bardziej ogólnie w limonkę. [fruit] sok w [fruit].

mapped_group = df.assign(
mapped_ingredient=lambda row: row["mapped_ingredient"].str.replace(" juice", "", regex=False)
).loc[
pd.isnull(df["alcohol_type"]), :
].groupby("mapped_ingredient").agg({
"cocktail_id": "nunique"
}).reset_index().sort_values("cocktail_id", ascending=False).head(25)

fig = go.Figure()
fig.add_trace(
go.Bar(
x=mapped_group["mapped_ingredient"],
y=mapped_group["cocktail_id"]
)
)

Mamy pewien ruch w danych. Konkretnie, 3 najlepsze składniki to owoce cytrusowe. Również grejpfrut awansował na 7. miejsce.

Teraz, gdy mamy już dobry pomysł na wygląd naszego wykresu słupkowego, możemy zacząć go prezentować. Wykresy słupkowe są interesujące, ponieważ podczas gdy większość typów wykresów wymaga etykiet na obu Zazwyczaj w przypadku wykresów słupkowych można pominąć oś Y zamiast bezpośrednich etykiet na górze słupków. Zazwyczaj lubię to robić, aby użytkownik nie musiał podążać za linią na ekranie.

Proszę najpierw dodać etykiety wykresu słupkowego:

fig = go.Figure()
fig.add_trace(
go.Bar(
x=mapped_group["mapped_ingredient"],
y=mapped_group["cocktail_id"],
text=mapped_group["cocktail_id"],
textposition="outside",
# This grabs the text attribute.
texttemplate="%{text}"
)
)

Jest kilka rzeczy, które mogą Państwo zauważyć lub wniosków, do których mogą Państwo dojść:

  1. Wyświetlanie etykiet osi i etykiet wykresu słupkowego jest zbędne, więc proszę zawsze wybierać jedno lub drugie. Moim zdaniem wyświetlanie etykiet wykresu słupkowego jest właściwym wyborem, aby użytkownik mógł natychmiast uzyskać dokładną wartość.
  2. 25 kategorii to zbyt wiele, jeśli chodzi o wyświetlanie etykiet wykresów słupkowych. Po prostu uważa jakby na stronie było za dużo liczb.
  3. Dane naprawdę zaczynają się spłaszczać w obszarze grenadyny i wiśni maraschino, które są odpowiednio 14. i 15. najczęściej używanym składnikiem.
  4. Pokazanie liczby bezwzględnej oczywiście pozwala nam porównać bary ze sobą, ale nie mówi nam o udziale w całym zestawie koktajli. Lepsze byłoby pokazanie % wszystkich koktajli, w których dany składnik jest używany.

Możemy rozwiązać #2 używając #3, po prostu ograniczając dane do 15 najlepszych zamiast 25 najlepszych.

mapped_group = df.assign(
mapped_ingredient=lambda row: row["mapped_ingredient"].str.replace(" juice", "", regex=False)
).loc[
pd.isnull(df["alcohol_type"]), :
].groupby("mapped_ingredient").agg({
"cocktail_id": "nunique"
}).reset_index().sort_values("cocktail_id", ascending=False).head(15)

Następnie utworzymy nową kolumnę dla % wszystkich koktajli.

mapped_group["perc_of_total"] = mapped_group["cocktail_id"]/len(df["cocktail_id"].unique())

fig = go.Figure()
fig.add_trace(
go.Bar(
x=mapped_group["mapped_ingredient"],
y=mapped_group["cocktail_id"],
text=mapped_group["perc_of_total"],
textposition="outside",
texttemplate="%{text:.1%}"
)
)
fig.show()

Wygląda już trochę lepiej, chociaż denerwuje mnie etykieta z wiśniami maraschino. Zajmę się tym później. Najpierw usuńmy zbędne informacje (i zmieńmy tło na białe).

Następnym krokiem powinno być dodanie tytułu osi y. Jeśli przeczytali Państwo mój artykuł o wykresach rozproszonychwyjaśniłem, jak obrócić tytuł, aby użytkownik nie musiał czytać z głową przekręconą w lewo. Chodzi o to, że należy dodać adnotację i umieścić ją w miejscu, w którym znajdowałby się tytuł, ponieważ Plotly nie pozwala natywnie na jego obracanie.

fig.add_annotation(
xref="paper", yref="paper",
x=-0.1,
y=0.5,
align="center",
text=f"% of Total<br>Cocktails",
font=dict(size=12),
showarrow=False
)

Wykres słupkowy jest już gotowy. Jedyne, co pozostało do zrobienia, to zhuzhowanie go (tak, zhuzh to prawdziwe słowo, proszę sprawdzić).

Wracając do tego, co powiedziałem o etykiecie z wiśniami maraschino, po prostu wystaje ona nieco bardziej niż bym chciał. Jest kilka opcji:

  1. Proszę zaktualizować etykietę tak, aby brzmiała “wiśnie”. To nie jest tak naprawdę opcja, ponieważ nie wszystkie wiśnie są takie same, a inne koktajle wykorzystują różne rodzaje wiśni.
  2. Proszę dodać podział wiersza dla długich etykiet. Nie jest to zła opcja, ale logika może być trudna, jeśli mają Państwo 2 słowa w składniku i próbują dowiedzieć się, gdzie zrobić przerwę (nie dotyczy to tego konkretnego przykładu). Ponadto, można napotkać etykiety nachodzące na siebie nawzajem
  3. Proszę zrobić poziomy wykres słupkowy!

W pierwszym artykule, do którego link podałem, przedstawiającym alternatywy dla wykresu słupkowego, jednym z nich jest “wykres rzędowy”. Autor podaje również powód, dla którego warto z niego skorzystać:

Jeśli etykiety danych byłyby nieco dłuższe – na przykład “Stany Zjednoczone Ameryki” – na pionowym wykresie słupkowym szybko zabrakłoby miejsca.

Przed obróceniem wykresu o 90 stopni musimy wykonać kilka kroków:

  1. Proszę zapewnić prawidłowe sortowanie (tj. cytryna i limonka są na górze).
  2. Proszę umieścić tytuł osi na dole (domyślnie jest na górze). Jeśli znajduje się na górze, będzie zbyt blisko tytułu.
  3. Proszę upewnić się, że odniesienia x i y zostały zamienione! Składniki powinny teraz znajdować się na osi y, a etykiety na osi x mają zostać ukryte.
fig = go.Figure()
fig.add_trace(
go.Bar(
y=mapped_group["mapped_ingredient"],
x=mapped_group["cocktail_id"],
text=mapped_group["perc_of_total"],
textposition="outside",
texttemplate="%{text:.2p}",
# This is all you need to do to make it a row chart
orientation="h",
)
)
fig.update_layout(
plot_bgcolor="white",
xaxis=dict(showticklabels=False),
# Ensure the correct sorting
yaxis={'categoryorder':'total ascending'},
)
# Move the annotation (axis label) to the bottom center of the chart
fig.add_annotation(
xref="paper", yref="paper",
x=0.5,
y=-0.1,
align="center",
text=f"% of Total Cocktails",
font=dict(size=14),
showarrow=False
)