Plotly 및 Clufflinks를 사용하여 Python에서 고품질 드로잉 그리기

최초 발표DataQoil.com.

상호작용 줄거리
이 블로그에는 대화형 드로잉을 구현하지 않는 정적 이미지가 포함되어 있으므로 방문을 요청합니다.

  • this 또는

  • this interactive blog .

  • 소개하다.
    안녕하십니까? 이 블로그에서 우리는 데이터 분석에서 가장 자주 사용되고 가장 간단한 그림을 탐색할 것입니다.만약 네가 데이터를 가지고 놀다가 손을 더럽혔다면, 적어도 어떤 줄거리도 만날 수 있을 것이다.Python에서는 Matplotlib을 사용하여 드로잉을 진행해 왔습니다.그러나 이외에, 우리는 Seaborn (Matplotlib 위에 구축된 것) 과 같은 도구를 가지고 있는데, 이것은 아름다운 도형을 사용할 수 있다.하지만 이것들은 모두 상호작용 줄거리가 아니다.플로리는 소통에 관한 거예요!
    이 블로그는 자주 업데이트될 것이다.
  • 2022년 1월 28일에 블로그를 쓰기 시작합니다.

  • 장치
    이 블로그는 구글 colab에서 준비하고 실행하는 것입니다. 로컬 컴퓨터에서 코드를 실행하려면 plotlypip install plotly를 설치하십시오.원하는 경우 official link에 액세스할 수 있습니다.그 다음은 소매 단추pip install cufflinks.
    import pandas as pd
    import numpy as np
    import warnings
    from plotly.offline import init_notebook_mode, iplot
    import plotly.figure_factory as ff
    import cufflinks
    import plotly.io as pio 
    cufflinks.go_offline()
    cufflinks.set_config_file(world_readable=True, theme='pearl')
    pio.renderers.default = "colab" # should change by looking into pio.renderers
    
    pd.options.display.max_columns = None
    # pd.options.display.max_rows = None
    
    pio.renderers
    
    Renderers configuration
    -----------------------
        Default renderer: 'colab'
        Available renderers:
            ['plotly_mimetype', 'jupyterlab', 'nteract', 'vscode',
             'notebook', 'notebook_connected', 'kaggle', 'azure', 'colab',
             'cocalc', 'databricks', 'json', 'png', 'jpeg', 'jpg', 'svg',
             'pdf', 'browser', 'firefox', 'chrome', 'chromium', 'iframe',
             'iframe_connected', 'sphinx_gallery', 'sphinx_gallery_png']
    
    colab에서 Plotly를 실행하고 있다면 pio.renderers.default = "colab" 을 사용하거나 필요에 따라 선택하십시오.

    데이터 세트 가져오기
    시각화를 위해 GitHub에 공개된 코로나 19호 데이터세트를 검토한다.

    Since the main goal of this blog is to explore visualization not the analysis part, we will be skipping most of analysis and focus only on the plots.


    df = pd.read_csv("https://covid.ourworldindata.org/data/owid-covid-data.csv")
    df["date"] = pd.to_datetime(df.date)
    df
    

    Data is not shown here to avoid huge page.


    157476행 x 67열

    누락된 열 확인
    모든 데이터 분석의 첫 번째 단계는 부족한 열을 검사하는 것이다.
    total = df.isnull().sum().sort_values(ascending = False)
    percent = (df.isnull().sum()/df.isnull().count()).sort_values(ascending = False)
    mdf = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
    mdf = mdf.reset_index()
    mdf
    
    인덱스
    총수
    퍼센트
    0
    매주 중환자 감호 병실에 입원하다
    153085
    0.972116
    1
    매주 중환자 감호 병실 백만 명당 입원 인원수
    153085
    0.972116
    2
    초과 사망률 백만 누적 사망률
    152056
    0.965582

    초과 사망률
    152056
    0.965582
    4
    초과 사망률 누적 절대치
    152056
    0.965582
    ...
    ...
    ...
    ...
    62
    개안 총수
    2850
    0.018098
    63
    인구
    1037
    0.006585
    64
    일자
    0
    0
    65
    위치:
    0
    0
    66
    iso 코드
    0
    0
    67행 x 3열
    우리는 부족한 데이터가 많은 것 같다. (97% +)

    떡그림

    값 열 없음
    떡그림에서 부족한 열을 그리는 계수는 어떻습니까?
    더 빨리 하기 위해서, 우리는 10만 개의 값이 부족한 열만 사용할 것이다.
    mdf.query("Total>100000").iplot(kind='pie',labels = "index", 
                                    values="Total", textinfo="percent+label",
                                    title='Top Columns with Missing Values', hole = 0.5)
    

    위의 줄거리가 좀 더러워 보이기 때문에 우리는 텍스트 정보를 제공하지 않아서 그것을 매끄럽게 할 수 있다.
    mdf.query("Total>100000").iplot(kind='pie',labels = "index", 
                                    values="Total",
                                    title='Top Columns with Missing Values', hole = 0.5)
    


    폴리라인 차트

    매일 신규 환자 발생
    Google 데이터의 위치 필드는 국가 이름, 대륙 이름, 세계를 포함하는 것 같습니다. 따라서 우선 이 위치를 건너뛰겠습니다.그리고 우리는 날짜 단계에 따라 조를 나누어 매일의 집합 값을 계산할 것이다
    우리는 먼저 간단한 접선도를 그려서 전체 사례만 보여 줍니다.하지만 우리는 그 안에 더 많은 선을 그릴 수 있다.
    todf = df[~df.location.isin(["Lower middle income", "North America", "World", "Asia", "Europe", 
                               "European Union", "Upper middle income", 
                               "High income", "South America"])]
    tdf = todf.groupby("date").aggregate(new_cases=("new_cases", "sum"),
                                       new_deaths = ("new_deaths", "sum"),
                                       new_vaccinations = ("new_vaccinations", "sum"),
                                       new_tests = ("new_tests", "sum")
                                       ).reset_index()
    
    tdf.iplot(kind="line",
              y="new_cases",
              x="date",
              xTitle="Date",
              width=2,
              yTitle="new_cases", 
              title="New Cases from Jan 2020 to Jan 2022")
    

    위의 그림은 멋있어 보이지만, 지금 우리는 같은 도형에 여러 개의 선을 동시에 그릴 것이다.
    tdf.iplot(kind="line",
              y=["new_deaths", "new_vaccinations", "new_tests"],
              x="date",
              xTitle="Date",
              width=2,
              yTitle="Cases", 
              title="Cases from Jan 2020 to Jan 2022")
    

    그것은 보기에 그다지 좋지 않다. 왜냐하면 새로운 죽음은 뚜렷하게 보이지 않기 때문이다. 우리는 그것들을 자도로 그려서, 이렇게 하면 우리는 모든 선을 똑똑히 볼 수 있다.
    tdf.iplot(kind="line",
              y=["new_deaths", "new_vaccinations", "new_tests"],
              x="date",
              xTitle="Date",
              width=2,
              yTitle="Cases", 
              subplots=True,
              title="Cases from Jan 2020 to Jan 2022")
    

    이제 좀 괜찮아졌어요.
    우리는 심지어 두 번째 y 변수를 그릴 수 있다.이제 새로운 테스트와 백신 접종을 함께 기획합시다.
    tdf.iplot(kind="line",
              y=["new_vaccinations"],
              secondary_y = "new_tests",
              x="date",
              xTitle="Date",
              width=2,
              yTitle="new_vaccinations",
              secondary_y_title="new_tests", 
              title="Cases from Jan 2020 to Jan 2022")
    

    위의 그림에서 우리는 두 개의 y축을 삽입할 수 있다.

    산점도

    새로운 사망과 새로운 병례
    산점도에서 사망과 병례를 살펴보는 것은 어떻습니까?
    tdf.iplot(kind="scatter",
                  y="new_deaths", x='new_cases',
                  mode='markers',
                  yTitle="New Deaths", xTitle="New Cases",
                  title="New Deaths vs New Cases")
    

    대부분의 사망은 병례가 매우 적을 때 발생하는 것 같다.
    우리는 심지어 차급 y를 그릴 수 있다. 우리는 함께 새로운 테스트를 상상해 보자.
    tdf.iplot(kind="scatter",
                  x="new_deaths", y='new_cases',
                  secondary_y="new_tests",
                  secondary_y_title="New Tests",
                  mode='markers',
                  xTitle="New Deaths", yTitle="New Cases",
                  title="New Deaths vs New Cases")
    

    우리는 심지어 위에서 하위 그림을 사용할 수 있다.
    tdf.iplot(kind="scatter",
                  x="new_deaths", y='new_cases',
                  secondary_y="new_tests",
                  secondary_y_title="New Tests",
                  mode='markers',
                  subplots=True,
                  xTitle="New Deaths", yTitle="New Cases",
                  title="New Deaths vs New Cases")
    


    막대 그래프
    그렇다면 사망자가 가장 많은 20개국의 지도를 그릴까?
    그러나 우선 전체 사망자의 최대치열을 추출해 집합 데이터를 얻는다.이 데이터 집합의 저자 덕분에 우리는 손을 너무 더럽힐 필요가 없다.그리고 nlargest를 사용하여 상위 20명을 선택한다.
    tdf = df[~df.location.isin(["Lower middle income", "North America", "World", "Asia", "Europe", 
                               "European Union", "Upper middle income", 
                               "High income", "South America"])].groupby("location").aggregate(total_deaths=("total_deaths", "max"),
                                                                                               total_cases = ("total_cases", "max"),
                                                                                               total_tests = ("total_tests", "max")).reset_index()
    topdf = tdf.nlargest(20, "total_deaths")
    
    
    topdf.iplot(kind="bar", x="location",
                                          y="total_deaths",
                                          theme="polar",
                                          xTitle="Countries", yTitle="Total Deaths", 
                                           title="Top 20 Countries according to total deaths")
    

    정말 멋있어 보여요.우리도 테마 게임을 할 수 있다.
    우리는 심지어 그것을 수준까지 끌어올릴 수 있다.
    topdf.iplot(kind="bar", x="location",
                y="total_deaths",
                theme="polar", orientation='h',
                xTitle="Countries", yTitle="Total Deaths", 
                title="Top 20 Countries according to total deaths")
    

    우리는 심지어 여러 개의 스트라이프를 동시에 그릴 수 있다.seaborn에서 우리는 색조를 사용하여 이 점을 실현할 수 있지만, 여기서는 y를 통해서만 할 수 있다. 총 사망, 총 병례, 총 검측의 스트라이프를 그려보자.
    topdf.iplot(kind="bar", x="location",
                y=["total_deaths", "total_cases", "total_tests"],
                theme="polar",
                xTitle="Countries", yTitle="Total Deaths", 
                title="Top 20 Countries according to total deaths")
    

    그러나 전체 사망자 수는 알 수 없으니 다른 술집 모드를 시도해 보자.우리는 'stack', 'group', 'overlay', 'relative' 중에서 하나를 선택할 수 있다.
    topdf.iplot(kind="bar", x="location",
                            y=["total_deaths", "total_cases", "total_tests"],
                            theme="polar",
                            barmode="overlay",
                            xTitle="Countries", yTitle="Total Deaths", 
                            title="Top 20 Countries according to total deaths")
    

    다만 아직 불분명하다.하나의 해결 방안은 하위 블록에 그리는 것이다.
    topdf.iplot(kind="bar", x="location",
                            y=["total_deaths", "total_cases", "total_tests"],
                            theme="polar",
                            barmode="overlay",
                            xTitle="Countries", yTitle="Total Deaths", 
                            subplots=True,
                            title="Top 20 Countries according to total deaths")
    

    많이 좋아졌어요.

    히스토그램
    토텔 테스트의 분포 상황을 보는 것은 어떻습니까?
    tdf.iplot(kind="hist",
                  bins=50, 
                  colors=["red"],
                  keys=["total_tests"],
                  title="Total tests Histogram")
    

    같은 그림의 다른 열의 기둥 모양 그림을 보려면 키를 사용합니다.
    tdf.iplot(kind="hist",
                  bins=100, 
                  colors=["red"],
                  keys=["total_tests", "total_cases", "total_deaths"],
                  title="Multiple Histogram")
    

    데이터 분포가 정확하지 않아 보기에 좋지 않다.우리는 그것을 다른 줄거리로 상상합시다.
    tdf.iplot(kind="hist",
                  subplots=True,
                  keys=["total_tests", "total_cases", "total_deaths"],
                  title="Multiple Histogram")
    


    박스 그래프
    데이터 중의 이상 값을 보는 것은 어떻습니까?
    tdf.iplot(kind="box",
                  keys=["total_tests", "total_cases", "total_deaths"], 
                  boxpoints="outliers",
                  x="location",
                  xTitle="Columns", title="Box Plot Tests, Cases and Deaths")
    

    데이터에 대량의 이상값이 존재하고 모든 열이 비슷한 분포를 가진 것은 아니기 때문에 뚜렷하게 보이지 않는다.
    tdf.iplot(kind="box",
                  keys=["total_tests", "total_cases", "total_deaths"], 
                  boxpoints="outliers",
                  x="location",
                  subplots=True,
                  xTitle="Columns", title="Box Plot Tests, Cases and Deaths")
    


    열도
    열 간의 연관성을 보는 것은 어떻습니까?우리는 모든 67열을 검사하지는 않지만, 3열로 테스트를 진행합시다.
    df[["new_cases", "new_deaths", "new_tests"]].corr().iplot(kind="heatmap")
    

    간단하지만 정보량이 많고 상호작용성이 강하죠?

    지도상에서 환호하며 깡충깡충 뛰다
    지도에 그림을 그리는 것이 꿈이었지만, 지금은 몇 번만 클릭하면 완성할 수 있다.

    우리 는 세계 지도 에서 최근 하루 까지 총 사망자 의 도표 를 그려 봅시다
    import plotly.graph_objects as go
    
    ldf = df[~df.location.isin(["Lower middle income", "North America", "World", "Asia", "Europe", 
                               "European Union", "Upper middle income", 
                               "High income", "South America"])].drop_duplicates("location", keep="last") 
    
    fig = go.Figure(data=go.Choropleth(
        locations = ldf['iso_code'],
        z = ldf['total_deaths'],
        text = ldf['location'],
        colorscale = 'Blues',
        autocolorscale=False,
        reversescale=True,
        marker_line_color='darkgray',
        marker_line_width=0.5,
        colorbar_title = 'total_deaths',
    ))
    
    fig.update_layout(
        title_text='total_deaths vs Country',
        geo=dict(
            showframe=False,
            showcoastlines=False,
            projection_type='equirectangular'
        )
    )
    
    fig.show()
    

    위의 그림은 현재 날짜만 표시하지만, 사용 가능한 날짜마다 데이터를 보려면 어떻게 해야 합니까?

    슬라이더 합창
    우리는 슬라이더를 추가해서 날짜에 따라 미끄러질 수 있지만, 이것은 전기를 너무 많이 소모하는 줄거리이기 때문에 시스템을 조심해야 한다.우리는 월말에 각 국가의 병례 총수를 그릴 것이다.
    tldf = df[~df.location.isin(["Lower middle income", "North America", "World", "Asia", "Europe", 
                               "European Union", "Upper middle income", 
                               "High income", "South America"])]
    tldf = tldf.groupby(["location", "iso_code", pd.Grouper(key="date", freq="1M")]).aggregate(total_cases=("total_cases", "max")).reset_index()
    tldf["date"] = tldf["date"].dt.date
    tldf
    
    
    위치:
    iso 코드
    일자
    개안 총수
    0
    아프간
    AFG
    2020-02-29
    5
    1
    아프간
    AFG
    2020-03-31
    166
    2
    아프간
    AFG
    2020-04-30
    1827

    아프간
    AFG
    2020-05-31
    15180
    4
    아프간
    AFG
    2020-06-30
    31445
    ...
    ...
    ...
    ...
    ...
    5101
    짐바브웨
    ZWE
    2021-09-30
    130820
    5102
    짐바브웨
    ZWE
    2021-10-31
    132977
    5103
    짐바브웨
    ZWE
    2021-11-30
    134625
    5104
    짐바브웨
    ZWE
    2021-12-31
    213258
    5105
    짐바브웨
    ZWE
    2022-01-31
    228943
    5106 행 x 4 열
    
    first_day = tldf.date.min()
    
    scl = [[0.0, '#ffffff'],[0.2, '#b4a8ce'],[0.4, '#8573a9'],
           [0.6, '#7159a3'],[0.8, '#5732a1'],[1.0, '#2c0579']] # purples
    
    data_slider = []
    for date in tldf['date'].unique():
        df_segmented =  tldf[(tldf['date']== date)]
    
        for col in df_segmented.columns:
            df_segmented[col] = df_segmented[col].astype(str)
    
        data_each_yr = dict(
                            type='choropleth',
                            locations = df_segmented['iso_code'],
                            z=df_segmented["total_cases"].astype(float),
                            colorbar= {'title':'Total Cases'}
                            )
    
        data_slider.append(data_each_yr)
    
    steps = []
    for i,date in enumerate(tldf.date.unique()):
        step = dict(method='restyle',
                    args=['visible', [False] * len(data_slider)],
                    label='Date {}'.format(date))
        step['args'][1][i] = True
        steps.append(step)
    
    sliders = [dict(active=0, pad={"t": 1}, steps=steps)]
    
    layout = dict(title ='Total Cases at the End of Month Across the World',
                  sliders=sliders)
    
    fig = dict(data=data_slider, layout=layout)
    iplot(fig)
    

    만약 내가 위의 코드를 설명해야 한다면, 우리는 이미 모든 미끄럼점에 데이터를 만들었고, 우리의 예에서 미끄럼점의 단일점은 월말이다.
  • 유일한 날짜를 순환적으로 봅니다.
  • 현재 날짜의 데이터를 얻기 위해 데이터를 차단합니다.
  • 제작chloropeth에 필요한 상용치와 기본치를 제시하여 사전을 제작한다.
  • 가 제시한 위치는iso_code이다.
  • z축을 총 사례로 제시한다.
  • 색상 표시줄 제목에 총 대소문자를 사용합니다.
  • 슬라이더에 데이터를 추가합니다.
  • 각 날짜 단계에 대한 레이블을 준비합니다.
  • 슬라이더와 레이아웃을 업데이트한 다음 iplot을 사용하여 그래픽과 드로잉을 그립니다.

  • 밀도 매핑 상자
    또 다른 유용한 그림은 밀도 프레임입니다. 지도에 밀도 그림을 그릴 것입니다.하지만 우리는 경도와 위도가 필요하다.나는 이미 GitHub에서 준비를 마쳤다.다음 링크를 참조하십시오.

  • State Location Coordinates
  • country_df = pd.read_csv("https://github.com/q-viper/State-Location-Coordinates/raw/main/world_country.csv")
    country_df = country_df[["country", "lon", "lat", "iso_con"]]
    tldf["country"] = tldf.location
    tldf = tldf.merge(country_df[["country", "lat", "lon"]], on="country")
    
    tldf.head()
    
    위치:
    iso 코드
    일자
    개안 총수
    국가.
    활용단어참조
    랑크스
    lat_y
    랑니
    0
    아프간
    AFG
    2020-02-29
    5
    아프간
    33.768006
    66.238514
    33.768006
    66.238514
    1
    아프간
    AFG
    2020-03-31
    166
    아프간
    33.768006
    66.238514
    33.768006
    66.238514
    2
    아프간
    AFG
    2020-04-30
    1827
    아프간
    33.768006
    66.238514
    33.768006
    66.238514

    아프간
    AFG
    2020-05-31
    15180
    아프간
    33.768006
    66.238514
    33.768006
    66.238514
    4
    아프간
    AFG
    2020-06-30
    31445
    아프간
    33.768006
    66.238514
    33.768006
    66.238514
    import plotly.express as px
    
    
    fig = px.density_mapbox(tldf.drop_duplicates(keep="last"), 
                              lat = tldf["lat"],
                              lon = tldf["lon"],
                              hover_name="location", 
                              hover_data=["total_cases"], 
                              color_continuous_scale="Portland",
                              radius=7, 
                              zoom=0,
                              height=700,
                              z="total_cases"
                              )
    fig.update_layout(title=f'Country vs total_cases',
                      font=dict(family="Courier New, monospace",
                                size=18,
                                color="#7f7f7f")
                    )
    fig.update_layout(mapbox_style="open-street-map", mapbox_center_lon=0)
    
    
    fig.show()
    

    우리가 주나 도시에서 그림을 그릴 때, 밀도도는 유용하고 또렷하다. 왜냐하면 그것은 우리의 그림을 약간 볼 수 있기 때문이다.여기는 잘 안 보여요.

    슬라이더가 있는 밀도 매핑 박스
    
    first_day = tldf.date.min()
    
    scl = [[0.0, '#ffffff'],[0.2, '#b4a8ce'],[0.4, '#8573a9'],
           [0.6, '#7159a3'],[0.8, '#5732a1'],[1.0, '#2c0579']] # purples
    
    data_slider = []
    for date in tldf['date'].unique():
        df_segmented =  tldf[(tldf['date']== date)]
    
        for col in df_segmented.columns:
            df_segmented[col] = df_segmented[col].astype(str)
    
        data_each_yr = dict(
                            type='densitymapbox',
                            lat = df_segmented["lat"],
                            lon = df_segmented["lon"],
                            hoverinfo="text",
                            # name = "country",
                            text = df_segmented["country"],                        
                            z=df_segmented["total_cases"].astype(float),
                            colorbar= {'title':'Total Cases'}
                            )
    
        data_slider.append(data_each_yr)
    
    steps = []
    for i,date in enumerate(tldf.date.unique()):
        step = dict(method='restyle',
                    args=['visible', [False] * len(data_slider)],
                    label='Date {}'.format(date))
        step['args'][1][i] = True
        steps.append(step)
    
    sliders = [dict(active=0, pad={"t": 1}, steps=steps)]
    
    layout = dict(mapbox_style="open-street-map",
                  title ='Total Cases at the End of Month Across the World',
                  sliders=sliders)
    
    fig = dict(data=data_slider, layout=layout)
    
    iplot(fig)
    


    도구책
  • Sliders
  • Cufflinks How To Create Plotly Charts From Pandas Dataframe With one Line of Code
  • 좋은 웹페이지 즐겨찾기