

seabornのviolinPlotで何とかなりますか？  
以下の図を作るために、アドバイスいただけると助かります。

#入力データと作図結果  
入力データ:  
dataA=[2,4,6,8,10,12,14]  
dataB=[3,6,9,12,15]

条件:  
① 横線に〇をプロットする。以下の図は正確ではありません。水平線上にマーク〇をプロットする。  
② 縦棒「|」を表示する。6と12が共通の値。

作図結果:  
dataA ――〇―――〇―――〇―――〇―――〇―――〇―――〇  
縦棒 | |  
dataB ――――〇―――――〇―――――〇―――――〇―――――〇

（次の行は不要です。説明用です。6と12の文字表示もできると、助かります。）  
１ ２ ３ 4 5 6 7 0 9 0 1 2 3 4 5

# 次のコードは、めちゃくちゃです。

[code]

    import matplotlib.pyplot as plt
    import numpy as np
    x = np.linspace(-1, 1, 100)
    y = np.sin(x)
    plt.plot(x, y)
    
[/code]


CC BY-SA 4.0
2021-02-28T05:00:14.683
74313
2021-03-02T13:08:37.980
2021-03-02T13:08:37.980
17199
17199
question
python matplotlib
matplotlibやseabornで1次元散布図(horizontal)をふたつ描いて、共通の点の間に線を引きたい


2 次元プロットの y 軸を表示しないことで 1
次元プロットに見せつつ、[`matplotlib.patches.ConnectionPatch`](https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.ConnectionPatch.html)
を使って共通部分に線を引けます。

[![](https://i.stack.imgur.com/pvVSG.png)](https://i.stack.imgur.com/pvVSG.png)

[code]

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.patches import ConnectionPatch
    
    def show_only_xaxis(ax):
        ax.spines["top"].set_visible(False)
        ax.spines["left"].set_visible(False)
        ax.spines["right"].set_visible(False)
        ax.spines["bottom"].set_position("zero")
        ax.get_xaxis().tick_bottom()
        ax.get_yaxis().set_visible(False)
    
    if __name__ == "__main__":
        data1 = [2, 4, 6, 8, 10, 12, 14]
        data2 = [3, 6, 9, 12, 15]
    
        fig, (ax1, ax2) = plt.subplots(2, 1)
    
        xlim_left = min(min(data1), min(data2)) - 1
        xlim_right = max(max(data1), max(data2)) + 1
        for ax in [ax1, ax2]:
            show_only_xaxis(ax)
            ax.set_xlim(xlim_left, xlim_right)
    
        ax1.scatter(data1, np.zeros_like(data1))
        ax2.scatter(data2, np.zeros_like(data2))
    
        intersection = set(data1).intersection(data2)
        for x in intersection:
            con = ConnectionPatch(
                xyA=(x, 0),
                xyB=(x, 0),
                coordsA="data",
                coordsB="data",
                axesA=ax1,
                axesB=ax2,
                color="red",
            )
            ax2.add_artist(con)
    
        plt.show()
    
[/code]

なお
[`seaborn.violinplot`](https://seaborn.pydata.org/generated/seaborn.violinplot.html)
は確率分布の箱ひげ図と密度関数（の推定）を描くためのもので、全く関係ありません。


CC BY-SA 4.0
2021-02-28T07:01:33.413
74315
2021-02-28T07:01:33.413
19110
74313
answer


> 縦棒を短くしたいです。
[code]

    import pandas as pd
    import matplotlib.pyplot as plt
    from matplotlib import collections as mc
    import seaborn as sns
    
    dataA = [2, 4, 6,  8, 10, 12, 14]
    dataB = [3, 6, 9, 12, 15]
    
    data = [['dataA', v] for v in dataA] + [['dataB', v] for v in dataB]
    df = pd.DataFrame(data, columns=['data', 'value'])
    
    plt.figure(1, figsize=(8, 2.4))
    ax = sns.stripplot(data=df, x='value', y='data', jitter=False, size=15)
    hc = mc.LineCollection(
      [[[0, n], [i, n]] for n, i in enumerate(map(max, (dataA, dataB)))],
      colors='k', linewidths=2)
    ax.add_collection(hc)
    lc = mc.LineCollection(
      [[[i, 0], [i, 1]] for i in set(dataA).intersection(dataB)],
      colors='red', linewidths=2)
    ax.add_collection(lc)
    
    ax.set_xlabel(''); ax.set_ylabel('')
    for p in ('right', 'left', 'top', 'bottom'):
      ax.spines[p].set_visible(False)
    ax.tick_params(
      left=False, bottom=False, labelleft=True, labelbottom=False)
    
    for n, l in enumerate((dataA, dataB)):
      for i in l:
        ax.text(
          x=i+0.1, y=n-0.05, s=i,
          horizontalalignment='left', verticalalignment='bottom',
          size='medium', color='k')
    
    plt.show()
    
[/code]

[![](https://i.stack.imgur.com/MzN43.png)](https://i.stack.imgur.com/MzN43.png)


CC BY-SA 4.0
2021-02-28T08:16:47.257
74317
2021-03-01T11:41:29.210
2021-03-01T11:41:29.210
74313
answer


追加の質問です。よろしくお願いします。  
①dataAとdataBの間隔を狭くする(入力する）方法を教えて下さい。  
縦棒を短くしたいです。

[code]

    import pandas as pd
    import matplotlib.pyplot as plt
    from matplotlib import collections as mc
    import seaborn as sns
    
    dataA = [2, 4, 6,  8, 10, 12, 14]
    dataB = [3, 6, 9, 12, 15]
    
    data = [['dataA', v] for v in (dataA)] + [['dataB', v] for v in (dataB)]
    df = pd.DataFrame(data, columns=['data', 'value'])
    ax = sns.stripplot(data=df, x='value', y='data', jitter=False, size=15)
    hc = mc.LineCollection(
      [[[0, n], [i, n]] for n, i in enumerate(map(max, (dataA, dataB)))],
      colors='k', linewidths=2)
    ax.add_collection(hc)
    lc = mc.LineCollection(
      [[[i, 0], [i, 1]] for i in set(dataA).intersection(dataB)],
      colors='red', linewidths=2)
    ax.add_collection(lc)
    for n, l in enumerate((dataA, dataB)):
      for i in l:
        ax.text(
          x=i+0.1, y=n-0.05, s=i,
          horizontalalignment='left', verticalalignment='bottom',
          size='medium', color='k')
    plt.gca().spines['left'].set_visible(False)
    plt.gca().spines['top'].set_visible(False)
    plt.gca().spines['right'].set_visible(False)
    plt.gca().spines['bottom'].set_visible(False)
    ax.tick_params(bottom=False,left=False,right=False,top=False)
    ax.set_xticks([])
    ax.set_xlabel("", size = "large", color ="green")
    ax.set_ylabel("", size = "large", color="blue")
    plt.show()
    
[/code]


CC BY-SA 4.0
2021-03-01T10:16:39.827
74340
2021-03-01T10:16:39.827
17199
74313
answer


> 何がしたいのかさっぱり分かりませんが、

申し訳ありません。説明不足でした。  
追加の質問です。

(目的)  
matplotlibで(整数問題)「2010年度 千葉大・医系数学 第4問」を作図してみたい。  
(問題)  
<https://www.densu.jp/chiba/10chibampass.pdf#page=4>  
(解答)  
<https://www.densu.jp/chiba/10chibampass.pdf#page=9>

次のコードは、「1次元散布図(1D scatter plot?)直し方を教えて下さい。」を参考にしました。  
問題点①dataAとdataBが,重なっている。離したい。2段に表示したい。Y座標位置を、入力したい。  
問題点②dataAとdataBを色分けしたい。  
問題点③dataAとdataBの同じ値の箇所は、縦棒を表示したい。  
問題点④数字81を、81(n=4)と表示したい。(又は、81の上に(n=4)と表示したい。任意の位置に文字を表示したい。  
アドバイスをいただけると、助かります。

[code]

    from sympy import *
    import pandas as pd
    import matplotlib.pyplot as plt
    from matplotlib import collections as mc
    import seaborn as sns
    
    def My_1dScatterPlot(My_Name,dataA,my_color,my_Yzahyo):
        df = pd.DataFrame([[My_Name, v] for v in dataA], columns=['data', 'value'])
    
        plt.figure(1, figsize=(6, 1))
        ax = sns.stripplot(data=df, x='value', y='data', jitter=False, size=8)
        hc = mc.LineCollection([[[0, 0], [max(dataA), 0]]], colors='k', linewidths=2)
        ax.add_collection(hc)
    
        for i in dataA:
          ax.text(
            x=i + 0.1, y=-0.01, s=i,
            horizontalalignment='left', verticalalignment='bottom',
            size='medium', color='k')
    
    def My_Nonlabel():
        ax.set_xlabel('');
        ax.set_ylabel('')
        for p in ('right', 'left', 'top', 'bottom'):
          ax.spines[p].set_visible(False)
        ax.tick_params(
          left=False, bottom=False, labelleft=True, labelbottom=False)
    
    # 第4問(2)
    var('colors coloru Yzahyos Yzahyou')
    sahen=[3**i    for i in range(1, 5+1)]
    uhen =[i**2-40 for i in range(7,17+1)]
    My_1dScatterPlot('3**n'   ,sahen,colors,Yzahyos)
    My_1dScatterPlot('k**2-40',uhen,coloru,Yzahyou)
    My_Nonlabel
    plt.show()
    
    # # 第4問(1)
    # # sahen = [3**i   for i in range(1,3+1)]
    # # uhen = [i**3+1 for i in range(1,3+1)]
    
[/code]


CC BY-SA 4.0
2021-03-02T13:06:54.467
74368
2021-03-02T13:06:54.467
17199
74313
answer