library(ggplot2)
Rのtidyverseで行う操作をPythonで書くとするとどうなるかを自分用にメモしておく。
データフレームの操作を行うライブラリとして、pandasとpolarsを使用した場合をそれぞれ書いてみる。
GitHub - pandas-dev/pandas: Flexible and powerful data analysis / manipulation library for Python, providing labeled data structures similar to R data.frame objects, statistical functions, and much more
Flexible and powerful data analysis / manipulation library for Python, providing labeled data structures similar to R data.frame objects, statistical functions, and much more - pandas-dev/pandas
https://github.com/pandas-dev/pandas
Polars
DataFrames for the new era
https://pola.rs/

準備
ライブラリの読み込み(必要であれば)
ライブラリの読み込み
import pandas as pd
import numpy as np
import polars as pl
import polars.selectors as cs
import matplotlib.pyplot as plt
from matplotlib.figure import Figure
from plotnine import ggplot, aes, geom_point
import seaborn.objects as so
import session_info
Code
# qmdだとなぜかpolarsのデータフレームがHTML形式でprintされるので、
# pl.DataFrameの_repr_html_をオーバーライドしておく
= print
pl.DataFrame._repr_html_
# polarsのデータフレームの表示設定をシンプルにする
(pl.Configformat='NOTHING')
.set_tbl_formatting(True)) .set_tbl_hide_dtype_separator(
tibble
tibble, as_tibble
データフレームの初期化方法。
# 直接作る
::tibble(
tibbleseisu = 0:4,
komoji = letters[1:5]
)
# A tibble: 5 × 2
seisu komoji
<int> <chr>
1 0 a
2 1 b
3 2 c
4 3 d
5 4 e
# listなど他のデータ型から変換
list(seisu = 0:4, komoji = letters[1:5]) |>
::as_tibble() tibble
# A tibble: 5 × 2
seisu komoji
<int> <chr>
1 0 a
2 1 b
3 2 c
4 3 d
5 4 e
= {
d 'seisu':[i for i in range(5)],
'komoji':[i for i in 'abcde']
}# 辞書から作る
pd.DataFrame(d)
seisu komoji
0 0 a
1 1 b
2 2 c
3 3 d
4 4 e
# リストから作る
for i,j in zip(d['seisu'], d['komoji'])], columns=d.keys()) pd.DataFrame([[i, j]
seisu komoji
0 0 a
1 1 b
2 2 c
3 3 d
4 4 e
= {
d 'seisu':[i for i in range(5)],
'komoji':[i for i in 'abcde']
}# 辞書から作る
pl.DataFrame(d)
shape: (5, 2)
seisu komoji
i64 str
0 a
1 b
2 c
3 d
4 e
# リストから作る
'seisu'], d['komoji']], schema=d.keys()) pl.DataFrame([d[
shape: (5, 2)
seisu komoji
i64 str
0 a
1 b
2 c
3 d
4 e
# pandasとはデータの持ち方が違うので元データが行方向の場合はorient='row'を指定する
for i,j in zip(d['seisu'], d['komoji'])],
pl.DataFrame([[i, j] =d.keys(), orient='row') schema
shape: (5, 2)
seisu komoji
i64 str
0 a
1 b
2 c
3 d
4 e
readr
read_csv
CSVファイルからのデータ読み込み。使用するCSVファイルは以下。
Code
cat << EOF > data.csv
"seisu","jissu","oomoji","komoji"
0,0.0,"A","a"
1,1.0,"A","b"
2,2.0,"B","c"
3,3.0,"B","d"
4,4.0,"C","e"
5,5.0,"D","f"
EOF
# readr::read_csvで読み込み。デフォルトだと整数も実数で読み込まれるのでデータ型を指定した。
<- readr::read_csv("data.csv", col_types = "idcc")
df df
# A tibble: 6 × 4
seisu jissu oomoji komoji
<int> <dbl> <chr> <chr>
1 0 0 A a
2 1 1 A b
3 2 2 B c
4 3 3 B d
5 4 4 C e
6 5 5 D f
= pd.read_csv('data.csv')
df_pd df_pd
seisu jissu oomoji komoji
0 0 0.0 A a
1 1 1.0 A b
2 2 2.0 B c
3 3 3.0 B d
4 4 4.0 C e
5 5 5.0 D f
= pl.read_csv('data.csv')
df_pl df_pl
shape: (6, 4)
seisu jissu oomoji komoji
i64 f64 str str
0 0.0 A a
1 1.0 A b
2 2.0 B c
3 3.0 B d
4 4.0 C e
5 5.0 D f
other formats
# TSV
|> readr::write_tsv("data.tsv.gz")
df ::read_tsv("data.tsv.gz")
readr
# PARQUET (arrowパッケージを利用)
|> arrow::write_parquet("data.parquet")
df ::read_parquet("data.parquet") arrow
# TSV
'data.tsv.gz', sep='\t', index=False)
df_pd.to_csv("data.tsv.gz", delimiter='\t')
pd.read_table(
# PARQUET
'data.parquet') # qmdのrender時にpyarrow.lib.ArrowKeyErrorが出る
df_pd.to_parquet("data.parquet") pd.read_parquet(
# TSV
'data.tsv.gz', separator='\t')
df_pl.write_csv("data.tsv.gz", separator='\t')
pl.read_csv(
# PARQUET
'data.parquet')
df_pl.write_parquet("data.parquet") pl.read_parquet(
dplyr
select
列の選択。
# 列のインデックス、列名で選択
|> dplyr::select(1, oomoji) df
# A tibble: 6 × 2
seisu oomoji
<int> <chr>
1 0 A
2 1 A
3 2 B
4 3 B
5 4 C
6 5 D
# 列のデータ型で選択
|> dplyr::select(tidyselect::where(is.numeric)) df
# A tibble: 6 × 2
seisu jissu
<int> <dbl>
1 0 0
2 1 1
3 2 2
4 3 3
5 4 4
6 5 5
# 列名で選択
'seisu', 'oomoji']] df_pd.loc[:, [
seisu oomoji
0 0 A
1 1 A
2 2 B
3 3 B
4 4 C
5 5 D
'jissu', 'komoji'], axis=1) df_pd.drop([
seisu oomoji
0 0 A
1 1 A
2 2 B
3 3 B
4 4 C
5 5 D
# 列のデータ型で選択
'number') df_pd.select_dtypes(
seisu jissu
0 0 0.0
1 1 1.0
2 2 2.0
3 3 3.0
4 4 4.0
5 5 5.0
# 列のインデックス、列名で選択
1, 'oomoji') df_pl.select(
shape: (6, 2)
literal oomoji
i32 str
1 A
1 A
1 B
1 B
1 C
1 D
# 列のデータ型で選択
df_pl.select(cs.numeric())
shape: (6, 2)
seisu jissu
i64 f64
0 0.0
1 1.0
2 2.0
3 3.0
4 4.0
5 5.0
mutate
新規列の追加、既存列の書き換え
|> dplyr::mutate(seisu=seisu / 2, nibai = jissu * 2) df
# A tibble: 6 × 5
seisu jissu oomoji komoji nibai
<dbl> <dbl> <chr> <chr> <dbl>
1 0 0 A a 0
2 0.5 1 A b 2
3 1 2 B c 4
4 1.5 3 B d 6
5 2 4 C e 8
6 2.5 5 D f 10
|> dplyr::mutate(dplyr::across(
df .cols = 1:2,
.fns = list(nibai = ~ . * 2, hanbun = ~ . / 2),
.names = "{.col}_{.fn}"
))
# A tibble: 6 × 8
seisu jissu oomoji komoji seisu_nibai seisu_hanbun jissu_nibai jissu_hanbun
<int> <dbl> <chr> <chr> <dbl> <dbl> <dbl> <dbl>
1 0 0 A a 0 0 0 0
2 1 1 A b 2 0.5 2 0.5
3 2 2 B c 4 1 4 1
4 3 3 B d 6 1.5 6 1.5
5 4 4 C e 8 2 8 2
6 5 5 D f 10 2.5 10 2.5
=lambda df: df.seisu/2, nibai=lambda df: df.jissu*2) df_pd.assign(seisu
seisu jissu oomoji komoji nibai
0 0.0 0.0 A a 0.0
1 0.5 1.0 A b 2.0
2 1.0 2.0 B c 4.0
3 1.5 3.0 B d 6.0
4 2.0 4.0 C e 8.0
5 2.5 5.0 D f 10.0
pd.concat(
[df_pd,'number').map(lambda x: x*2)
(df_pd.select_dtypes(lambda x: x+'_nibai', axis=1)),
.rename('number').map(lambda x: x/2)
(df_pd.select_dtypes(lambda x: x+'_hanbun', axis=1))
.rename(
],=1
axis )
seisu jissu oomoji ... jissu_nibai seisu_hanbun jissu_hanbun
0 0 0.0 A ... 0.0 0.0 0.0
1 1 1.0 A ... 2.0 0.5 0.5
2 2 2.0 B ... 4.0 1.0 1.0
3 3 3.0 B ... 6.0 1.5 1.5
4 4 4.0 C ... 8.0 2.0 2.0
5 5 5.0 D ... 10.0 2.5 2.5
[6 rows x 8 columns]
pd.concat(
[df_pd,'number')
(df_pd.select_dtypes(apply([lambda x: x*2, lambda x: x/2]))
.
],=1
axis )
seisu jissu oomoji ... (seisu, <lambda>) (jissu, <lambda>) (jissu, <lambda>)
0 0 0.0 A ... 0.0 0.0 0.0
1 1 1.0 A ... 0.5 2.0 0.5
2 2 2.0 B ... 1.0 4.0 1.0
3 3 3.0 B ... 1.5 6.0 1.5
4 4 4.0 C ... 2.0 8.0 2.0
5 5 5.0 D ... 2.5 10.0 2.5
[6 rows x 8 columns]
"jissu") * 2).alias("nibai")) df_pl.with_columns((pl.col(
shape: (6, 5)
seisu jissu oomoji komoji nibai
i64 f64 str str f64
0 0.0 A a 0.0
1 1.0 A b 2.0
2 2.0 B c 4.0
3 3.0 B d 6.0
4 4.0 C e 8.0
5 5.0 D f 10.0
(df_pl
.with_columns(* 2).name.suffix("_nibai"),
(cs.numeric() / 2).name.suffix("_hanbun")
(cs.numeric()
) )
shape: (6, 8)
seisu jissu oomoji komoji seisu_nibai jissu_nibai seisu_hanbun jissu_hanbun
i64 f64 str str i64 f64 f64 f64
0 0.0 A a 0 0.0 0.0 0.0
1 1.0 A b 2 2.0 0.5 0.5
2 2.0 B c 4 4.0 1.0 1.0
3 3.0 B d 6 6.0 1.5 1.5
4 4.0 C e 8 8.0 2.0 2.0
5 5.0 D f 10 10.0 2.5 2.5
filter
条件に一致する行を抽出。
|> dplyr::filter(jissu >= 2) df
# A tibble: 4 × 4
seisu jissu oomoji komoji
<int> <dbl> <chr> <chr>
1 2 2 B c
2 3 3 B d
3 4 4 C e
4 5 5 D f
|> dplyr::filter(oomoji %in% c("A", "B", "C")) df
# A tibble: 5 × 4
seisu jissu oomoji komoji
<int> <dbl> <chr> <chr>
1 0 0 A a
2 1 1 A b
3 2 2 B c
4 3 3 B d
5 4 4 C e
'jissu'] >= 2, :] df_pd.loc[df_pd[
seisu jissu oomoji komoji
2 2 2.0 B c
3 3 3.0 B d
4 4 4.0 C e
5 5 5.0 D f
"oomoji in ['A', 'B', 'C']") df_pd.query(
seisu jissu oomoji komoji
0 0 0.0 A a
1 1 1.0 A b
2 2 2.0 B c
3 3 3.0 B d
4 4 4.0 C e
filter(pl.col("jissu") >= 2) df_pl.
shape: (4, 4)
seisu jissu oomoji komoji
i64 f64 str str
2 2.0 B c
3 3.0 B d
4 4.0 C e
5 5.0 D f
filter(pl.col("oomoji").is_in(['A', 'B', 'C'])) df_pl.
shape: (5, 4)
seisu jissu oomoji komoji
i64 f64 str str
0 0.0 A a
1 1.0 A b
2 2.0 B c
3 3.0 B d
4 4.0 C e
arrange
行の並べ替え。
|> dplyr::arrange(oomoji, dplyr::desc(seisu)) df
# A tibble: 6 × 4
seisu jissu oomoji komoji
<int> <dbl> <chr> <chr>
1 1 1 A b
2 0 0 A a
3 3 3 B d
4 2 2 B c
5 4 4 C e
6 5 5 D f
'oomoji', 'seisu'], ascending=[True, False]) df_pd.sort_values([
seisu jissu oomoji komoji
1 1 1.0 A b
0 0 0.0 A a
3 3 3.0 B d
2 2 2.0 B c
4 4 4.0 C e
5 5 5.0 D f
= ['oomoji', 'seisu'], descending=[False, True]) df_pl.sort(by
shape: (6, 4)
seisu jissu oomoji komoji
i64 f64 str str
1 1.0 A b
0 0.0 A a
3 3.0 B d
2 2.0 B c
4 4.0 C e
5 5.0 D f
group_by -> summarise
変数でグループ化して集約する。
|>
df ::summarise(
dplyr.by = oomoji,
seisu_gokei = sum(seisu)
)
# A tibble: 4 × 2
oomoji seisu_gokei
<chr> <int>
1 A 1
2 B 5
3 C 4
4 D 5
(df_pd'oomoji')
.groupby(=('seisu', np.sum))
.agg(seisu_gokei .reset_index())
<string>:3: FutureWarning: The provided callable <function sum at 0x11239ff60> is currently using SeriesGroupBy.sum. In a future version of pandas, the provided callable will be used directly. To keep current behavior pass the string "sum" instead.
oomoji seisu_gokei
0 A 1
1 B 5
2 C 4
3 D 5
(df_pl'oomoji')
.group_by('seisu').sum().alias('seisu_gokei'))) .agg(pl.col(
shape: (4, 2)
oomoji seisu_gokei
str i64
D 5
A 1
C 4
B 5
distinct
重複のない観測データ(行)のみ残す。
|>
df ::select(oomoji) |>
dplyr::distinct() dplyr
# A tibble: 4 × 1
oomoji
<chr>
1 A
2 B
3 C
4 D
(df_pd'oomoji']] # 列はリストで指定しないとpd.Seriesになってしまう
.loc[:, [ .drop_duplicates())
oomoji
0 A
2 B
4 C
5 D
(df_pl'oomoji'))
.select(pl.col( .unique())
shape: (4, 1)
oomoji
str
C
B
A
D
glimpse
列が多数ある場合に見やすく表示する。
|> dplyr::group_by(oomoji) |> dplyr::glimpse() df
Rows: 6
Columns: 4
Groups: oomoji [4]
$ seisu <int> 0, 1, 2, 3, 4, 5
$ jissu <dbl> 0, 1, 2, 3, 4, 5
$ oomoji <chr> "A", "A", "B", "B", "C", "D"
$ komoji <chr> "a", "b", "c", "d", "e", "f"
pd.DataFrameにはglimpseメソッドはない。
def glimpse(df):
print(f"Rows: {df.shape[0]}")
print(f"Columns: {df.shape[1]}")
for col in df.columns:
print(f"$ {col} <{df[col].dtype}> {df[col].head().values}")
glimpse(df_pd)
Rows: 6
Columns: 4
$ seisu <int64> [0 1 2 3 4]
$ jissu <float64> [0. 1. 2. 3. 4.]
$ oomoji <object> ['A' 'A' 'B' 'B' 'C']
$ komoji <object> ['a' 'b' 'c' 'd' 'e']
Above codes are borrowed from this stackoverflow
# pl.DataFrameはglimpseメソッドがあるがgroup_byすると使えない
df_pl.glimpse()
Rows: 6
Columns: 4
$ seisu <i64> 0, 1, 2, 3, 4, 5
$ jissu <f64> 0.0, 1.0, 2.0, 3.0, 4.0, 5.0
$ oomoji <str> 'A', 'A', 'B', 'B', 'C', 'D'
$ komoji <str> 'a', 'b', 'c', 'd', 'e', 'f'
*_join
join関数
<- df[c(1,3,5), c(1,3)]
dfl <- df[c(2,4,6), c(2,3)]
dfr
|> dplyr::left_join(dfr, by = "oomoji") dfl
# A tibble: 3 × 3
seisu oomoji jissu
<int> <chr> <dbl>
1 0 A 1
2 2 B 3
3 4 C NA
|> dplyr::right_join(dfr, by = "oomoji") dfl
# A tibble: 3 × 3
seisu oomoji jissu
<int> <chr> <dbl>
1 0 A 1
2 2 B 3
3 NA D 5
|> dplyr::inner_join(dfr, by = "oomoji") dfl
# A tibble: 2 × 3
seisu oomoji jissu
<int> <chr> <dbl>
1 0 A 1
2 2 B 3
|> dplyr::full_join(dfr, by = "oomoji") dfl
# A tibble: 4 × 3
seisu oomoji jissu
<int> <chr> <dbl>
1 0 A 1
2 2 B 3
3 4 C NA
4 NA D 5
= df_pd.loc[[0,2,4], ['seisu','oomoji']]
dfl_pd = df_pd.loc[[1,3,5], ['jissu','oomoji']]
dfr_pd
='oomoji', how='left') dfl_pd.merge(dfr_pd, on
seisu oomoji jissu
0 0 A 1.0
1 2 B 3.0
2 4 C NaN
='oomoji', how='right') dfl_pd.merge(dfr_pd, on
seisu oomoji jissu
0 0.0 A 1.0
1 2.0 B 3.0
2 NaN D 5.0
='oomoji', how='inner') dfl_pd.merge(dfr_pd, on
seisu oomoji jissu
0 0 A 1.0
1 2 B 3.0
='oomoji', how='outer') dfl_pd.merge(dfr_pd, on
seisu oomoji jissu
0 0.0 A 1.0
1 2.0 B 3.0
2 4.0 C NaN
3 NaN D 5.0
= df_pl[[0,2,4], ['seisu','oomoji']]
dfl_pl = df_pl[[1,3,5], ['jissu','oomoji']]
dfr_pl
='oomoji', how='left') dfl_pl.join(dfr_pl, on
shape: (3, 3)
seisu oomoji jissu
i64 str f64
0 A 1.0
2 B 3.0
4 C null
='oomoji', how='right') dfl_pl.join(dfr_pl, on
shape: (3, 3)
seisu jissu oomoji
i64 f64 str
0 1.0 A
2 3.0 B
null 5.0 D
='oomoji', how='inner') dfl_pl.join(dfr_pl, on
shape: (2, 3)
seisu oomoji jissu
i64 str f64
0 A 1.0
2 B 3.0
='oomoji', how='full') dfl_pl.join(dfr_pl, on
shape: (4, 4)
seisu oomoji jissu oomoji_right
i64 str f64 str
0 A 1.0 A
2 B 3.0 B
null null 5.0 D
4 C null null
='oomoji', how='full', coalesce=True) dfl_pl.join(dfr_pl, on
shape: (4, 3)
seisu oomoji jissu
i64 str f64
0 A 1.0
2 B 3.0
null D 5.0
4 C null
tidyr
pivot_longer
データフレームを縦長に変形
|> tidyr::pivot_longer(cols = 1:2) df
# A tibble: 12 × 4
oomoji komoji name value
<chr> <chr> <chr> <dbl>
1 A a seisu 0
2 A a jissu 0
3 A b seisu 1
4 A b jissu 1
5 B c seisu 2
6 B c jissu 2
7 B d seisu 3
8 B d jissu 3
9 C e seisu 4
10 C e jissu 4
11 D f seisu 5
12 D f jissu 5
=['oomoji', 'komoji'], value_vars=['seisu', 'jissu']) df_pd.melt(id_vars
oomoji komoji variable value
0 A a seisu 0.0
1 A b seisu 1.0
2 B c seisu 2.0
3 B d seisu 3.0
4 C e seisu 4.0
5 D f seisu 5.0
6 A a jissu 0.0
7 A b jissu 1.0
8 B c jissu 2.0
9 B d jissu 3.0
10 C e jissu 4.0
11 D f jissu 5.0
=['seisu', 'jissu'], index=['oomoji', 'komoji']) df_pl.unpivot(on
shape: (12, 4)
oomoji komoji variable value
str str str f64
A a seisu 0.0
A b seisu 1.0
B c seisu 2.0
B d seisu 3.0
C e seisu 4.0
… … … …
A b jissu 1.0
B c jissu 2.0
B d jissu 3.0
C e jissu 4.0
D f jissu 5.0
pivot_wider
データフレームを横長に変形
|>
df ::pivot_longer(cols = 1:2) |>
tidyr::pivot_wider() tidyr
# A tibble: 6 × 4
oomoji komoji seisu jissu
<chr> <chr> <dbl> <dbl>
1 A a 0 0
2 A b 1 1
3 B c 2 2
4 B d 3 3
5 C e 4 4
6 D f 5 5
(df_pd=['oomoji', 'komoji'], value_vars=['seisu', 'jissu'])
.melt(id_vars='variable', index=['oomoji', 'komoji'], values='value')
.pivot(columns .reset_index())
variable oomoji komoji jissu seisu
0 A a 0.0 0.0
1 A b 1.0 1.0
2 B c 2.0 2.0
3 B d 3.0 3.0
4 C e 4.0 4.0
5 D f 5.0 5.0
(df_pl=['seisu', 'jissu'], index=['oomoji', 'komoji'])
.unpivot(on'variable', index=['oomoji', 'komoji'], values='value')) .pivot(
shape: (6, 4)
oomoji komoji seisu jissu
str str f64 f64
A a 0.0 0.0
A b 1.0 1.0
B c 2.0 2.0
B d 3.0 3.0
C e 4.0 4.0
D f 5.0 5.0
ggplot2
プロットが一つの場合
Code
<- function() {
theme_matplotlib_like list(
theme(
panel.background = element_rect(fill = NA, colour = "black"),
panel.grid = element_blank(),
legend.key = element_blank()
),scale_color_viridis_d(option = "E"),
scale_fill_viridis_d(option = "E")
) }
Code
= plt.get_cmap("cividis")
cmap = (
df_pl_plot
df_pl.with_columns("oomoji")
pl.col("dense")
.rank(
.cast(pl.Int64)"oomoji_color")
.alias(
).with_columns("oomoji_color") / pl.col("oomoji_color").max())
(pl.col(lambda x: cmap(x), return_dtype=pl.Object)
.map_elements(
) )
ほぼggplot2
と同じような感じにかける。
複数のプロットを組み合わせる
<- df |>
gp1 ggplot(aes(seisu, jissu)) +
geom_point(aes(color = oomoji, shape = komoji), size = 5)
<- df |>
gp2 ggplot(aes(komoji, jissu)) +
geom_col(aes(fill = oomoji)) +
scale_y_continuous(expand = expansion(c(0, 0.1)))
<- df |>
gp3 ggplot(aes(komoji, jissu)) +
geom_line(aes(group=""))
::wrap_plots(gp1, gp2, gp3, ncol = 3, guides = "collect") &
patchworktheme_matplotlib_like() &
theme(legend.direction = "horizontal")
= plt.subplots(1, 3)
fig, axs = axs[0].scatter('seisu', 'jissu', c='oomoji_color', s=100, data=df_pl_plot)
sc # produce a legend with the unique colors from the scatter
= axs[0].legend(*sc.legend_elements(), loc="lower left")
legend1 0].add_artist(legend1)
axs[0].legend()
axs[1].bar('komoji', 'jissu', color='oomoji_color', data=df_pl_plot)
axs[1].legend()
axs[2].plot(df_pl_plot['komoji'], df_pl_plot['jissu'])
axs[2].legend() axs[
別パターン
patchworklib v0.6.5
を使うとplotnine v0.13.6
まではできたようだが、 plotnine v0.14.1
では現状未対応となっている。
= (
so1 ='seisu', y='jissu')
so.Plot(df_pl_plot.to_pandas(), x=6), color='oomoji', marker='komoji')
.add(so.Dot(pointsize
.scale()
)= (
so2 ='komoji', y='jissu')
so.Plot(df_pl_plot.to_pandas(), x='oomoji')
.add(so.Bar(), color
.scale()
)= (
so3 ='komoji', y='jissu')
so.Plot(df_pl_plot.to_pandas(), x
.add(so.Line())
)= plt.figure(clear=True, layout='constrained')
f = f.subfigures(1, 4, width_ratios=(1,1,1,0.5))
sfs for sf, soi in zip(sfs, [so1, so2, so3]):
= soi.on(sf).plot()
_
= ["upper center", "center", "lower center"]
pos = 0
i while True:
try:
= f.legends.pop()
l except:
break
= sfs[-1].legend(l.legend_handles, [t.get_text() for t in l.texts], loc=pos[i])
_ += 1 i
複数のlegendをうまく取り扱うことができない。 まず普通にするとlegendが見切れて表示されないし、 ここで示すようにlegendを取り出して表示するようにしてもmarkerのlegendが消えてしまって表示できない。
感想
pandasに比べると、mutate関連の操作などではpolarsの方が簡潔にかけるように感じた。
参考
python pandas と R tidyverseの比較 - Qiita
Rのtidyverseパッケージ群は、データの操作や可視化を簡潔で一貫した記述で行うことができる非常に優れたツールで、私も愛してやみません。しかし、最近はシステムにモデルを組み込んだり、ディープラ…
https://qiita.com/shush/items/2c074e0bc057fbe41dd0

R/tidyverseとPython/polarsの比較 - Qiita
はじめに備忘として、データフレーム操作におけるRのtidyverse (主にdplyr)からpythonのpolarsへの書き換えを順次更新していきます。Rからpythonに移行したものの、pa…
https://qiita.com/nutb/items/702d1acb73043d49e8c6

Sessioninfo
sessionInfo()
R version 4.3.2 (2023-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Ventura 13.1
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.11.0
locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: Asia/Tokyo
tzcode source: internal
attached base packages:
[1] stats graphics grDevices datasets utils methods base
other attached packages:
[1] ggplot2_3.5.1
loaded via a namespace (and not attached):
[1] bit_4.0.5 Matrix_1.6-1.1 gtable_0.3.5 jsonlite_1.8.8
[5] crayon_1.5.2 dplyr_1.1.4 compiler_4.3.2 renv_1.0.10
[9] tidyselect_1.2.1 Rcpp_1.0.13 parallel_4.3.2 tidyr_1.3.1
[13] scales_1.3.0 png_0.1-8 yaml_2.3.9 fastmap_1.1.1
[17] reticulate_1.39.0 lattice_0.21-9 readr_2.1.5 R6_2.5.1
[21] patchwork_1.2.0 labeling_0.4.3 generics_0.1.3 knitr_1.48
[25] tibble_3.2.1 munsell_0.5.1 pillar_1.9.0 tzdb_0.4.0
[29] rlang_1.1.4 utf8_1.2.4 xfun_0.46 bit64_4.0.5
[33] viridisLite_0.4.2 cli_3.6.3 withr_3.0.0 magrittr_2.0.3
[37] digest_0.6.34 grid_4.3.2 vroom_1.6.5 hms_1.1.3
[41] lifecycle_1.0.4 vctrs_0.6.5 evaluate_0.24.0 glue_1.7.0
[45] farver_2.1.2 fansi_1.0.6 colorspace_2.1-1 purrr_1.0.2
[49] rmarkdown_2.25 tools_4.3.2 pkgconfig_2.0.3 htmltools_0.5.7
session_info.show()