Seaborn: Поверните сюжет и сопоставьте подзаголовок оси

#python #matplotlib #seaborn

Вопрос:

Я хотел бы повернуть левый график так, чтобы текущая ось x стала осью y и совпадала с осью на правом графике.

Воспроизводимый пример ниже:

 import pandas as pd
import requests
import datetime
import matplotlib.pyplot as plt
import seaborn as sns

def spread(tick):
  # data for left plot
  r = requests.get("https://api.binance.com/api/v3/depth",
                  params=dict(symbol=tick))
  results = r.json()
  frames = {side: pd.DataFrame(data=results[side], columns=["price", "quantity"],
                              dtype=float)
            for side in ["bids", "asks"]}
  frames_list = [frames[side].assign(side=side) for side in frames]
  df = pd.concat(frames_list, axis="index", 
                  ignore_index=True, sort=True)
  
  # data for right plot
  url = 'https://api.binance.com/api/v3/klines'
  params = {
    'symbol': tick,
    'interval': '1m'
  }
  r = requests.get(url, params=params)
  results = r.json()
  prices = pd.DataFrame.from_records(results)
  prices.columns = ['Open time', 'Open','High','Low','Close','Volume','Close time','Quote asset volume','Number of trades','Taker buy base asset volume','Taker buy quote asset volume','Ignore.']
  prices['Open time'] = pd.to_datetime(prices['Open time'], unit='ms', errors='coerce')
  prices = prices.set_index('Open time')
  prices['Close'] = pd.to_numeric(prices['Close'])
  

  # plot
  sns.set_style("whitegrid")
  plt.style.use('seaborn-dark-palette')
  f, (ax1, ax2) = plt.subplots(1, 2,figsize=(20,5),gridspec_kw={'width_ratios': [1, 2.5]}, dpi= 300, 
                               facecolor='w', edgecolor='k')

  # left plot 
  ax1.set_title(f"{tick} SPREAD at {datetime.datetime.now()}")
  sns.ecdfplot(x="price", weights="quantity", stat="count", complementary=True, data=frames["bids"], ax=ax1)
  sns.ecdfplot(x="price", weights="quantity", stat="count", data=frames["asks"], ax=ax1)
  sns.histplot(x="price", weights="quantity", hue="side", binwidth=0.02, bins=20, data=df, ax=ax1)
  sns.scatterplot(x="price", y="quantity", hue="side", data=df, ax=ax1)
  ax1.set_xlabel("Price")
  ax1.set_xticks(df.price, minor=True)
  ax1.set_ylabel("Quantity")

  # right plot
  ax2.plot(prices.index, prices['Close'], alpha = 1)
  ax2.set_title(f'{tick} Price')
  ax2.set_xlabel('Date')

  return plt.show()
 

Приведенная выше функция считывает данные и строит два графика рядом. Однако левый участок следует повернуть так, чтобы ось x совпадала с осью y правого участка.

 spread('BTCUSDT')
 

участок распространения

Комментарии:

1. При совместном использовании осей вы хотите, чтобы значения совпадали одинаково или вы хотели бы, чтобы они были просто ценой?

2. идентично совпадают

3. Звучит хорошо. Как указано в ответе, просто раскомментируйте последнюю строку, чтобы разделить оси y для обоих подзаголовков. Надеюсь, это поможет!

4. Я не уверен, что понимаю природу самого вопроса, но намерены ли вы просто изменить оси x и y графика справа?

Ответ №1:

Просто измените ecdfplot scatterplot , histplot , и т.д. так, чтобы y = price и x = quantity там, где это применимо. Вот измененная функция:

 import pandas as pd
import requests
import datetime
import matplotlib.pyplot as plt
import seaborn as sns

def spread(tick):
  # data for left plot
  r = requests.get("https://api.binance.com/api/v3/depth",
                  params=dict(symbol=tick))
  results = r.json()
  frames = {side: pd.DataFrame(data=results[side], columns=["price", "quantity"],
                              dtype=float)
            for side in ["bids", "asks"]}
  frames_list = [frames[side].assign(side=side) for side in frames]
  df = pd.concat(frames_list, axis="index", 
                  ignore_index=True, sort=True)
  
  # data for right plot
  url = 'https://api.binance.com/api/v3/klines'
  params = {
    'symbol': tick,
    'interval': '1m'
  }
  r = requests.get(url, params=params)
  results = r.json()
  prices = pd.DataFrame.from_records(results)
  prices.columns = ['Open time', 'Open','High','Low','Close','Volume','Close time','Quote asset volume','Number of trades','Taker buy base asset volume','Taker buy quote asset volume','Ignore.']
  prices['Open time'] = pd.to_datetime(prices['Open time'], unit='ms', errors='coerce')
  prices = prices.set_index('Open time')
  prices['Close'] = pd.to_numeric(prices['Close'])
  

  # plot
  sns.set_style("whitegrid")
  plt.style.use('seaborn-dark-palette')
  f, (ax1, ax2) = plt.subplots(1, 2,figsize=(20,5),gridspec_kw={'width_ratios': [1, 2.5]}, dpi= 300, 
                               facecolor='w', edgecolor='k')

  # left plot
  # Modified so that price is y and quantity is x
  ax1.set_title(f"{TICK} SPREAD at {datetime.datetime.now()}")
  sns.ecdfplot(y="price", weights="quantity", stat="count", complementary=True, data=frames["bids"], ax=ax1)
  sns.ecdfplot(y="price", weights="quantity", stat="count", data=frames["asks"], ax=ax1)

  sns.histplot(y="price", weights="quantity", hue="side", binwidth=0.02, bins=20, data=df, ax=ax1)

  sns.scatterplot(x="quantity", y="price", hue="side", data=df, ax=ax1)
  ax1.set_xlabel("Quantity")
  ax1.set_yticks(df.price, minor=True)
  ax1.set_ylabel("Price")

  # right plot
  ax2.plot(prices.index, prices['Close'], alpha = 1)
  ax2.set_title(f'{tick} Price')
  ax2.set_xlabel('Date')

  # Share y-axis between subplots
  # if you want to merge axes values, uncomment this line
  ax1.get_shared_y_axes().join(ax1, ax2)

  return plt.show()
 

который строит этот:

ИЗМЕНИТЬ: Функция обновлена для совместного использования значений оси y в обоих подзаголовках

 spread('BTCUSDT')
 

введите описание изображения здесь