Closed ersinesen closed 8 months ago
I want to plot mappings between two ranges. For instance, x is the independent variable and f1, f2 corresponding ranges:
x = [1, 2, 3, 4, 5] f1 = [(0, 20), (20, 40), (40, 60), (60, 80), (80, 100)] f2 = [(0, 80), (80, 95), (95, 98), (98, 99), (99, 100)]
import matplotlib.pyplot as plt # Data x = [1, 2, 3, 4, 5] f1 = [(0, 20), (20, 40), (40, 60), (60, 80), (80, 100)] f2 = [(0, 80), (80, 95), (95, 98), (98, 99), (99, 100)] # Define colors for each segment colors = ['red', 'blue', 'green', 'orange', 'purple'] # Parameters W = 0.1 # Width of each bar D = 1 # Distance between bars # Plotting fig, ax = plt.subplots(figsize=(8, 6)) # Plotting stacked bars for f1 for i, segment in enumerate(f1): ax.bar(-1 * D, segment[1] - segment[0], bottom=segment[0], width=W, color=colors[i]) # Plotting stacked bars for f2 for i, segment in enumerate(f2): ax.bar(1 * D, segment[1] - segment[0], bottom=segment[0], width=W, color=colors[i]) # Adding arrows to show mapping for i in range(len(x)): ax.annotate('', xy=(-1 * D + W/2, f1[i][0]), xytext=(1 * D - W/2, f2[i][0]), arrowprops=dict(facecolor='black', arrowstyle='-')) ax.annotate('', xy=(-1 * D + W/2, f1[i][1]), xytext=(1 * D - W/2, f2[i][1]), arrowprops=dict(facecolor='black', arrowstyle='-')) # Removing grid lines, y-axis label, and axis ticks ax.grid(False) ax.set_yticks([]) ax.set_ylabel('') ax.set_xticks([]) ax.set_title('Range Mapping: Bar to Bar') plt.show()
import matplotlib.pyplot as plt import numpy as np # Data x = [1, 2, 3, 4, 5] f1 = [(0, 20), (20, 40), (40, 60), (60, 80), (80, 100)] f2 = [(0, 80), (80, 95), (95, 98), (98, 99), (99, 100)] # Define colors for each segment colors = ['red', 'blue', 'green', 'orange', 'purple'] # Parameters W = 5 # Width of each bar D = 10 # Distance between bars R = 50 # Radius of arcs for f2 arc_width = 5 # Width of the circle arcs # Plotting fig, ax = plt.subplots(figsize=(8, 6)) # Plotting stacked bars for f1 for i, segment in enumerate(f1): ax.barh(0, segment[1] - segment[0], left=segment[0], height=W, color=colors[i]) # Plotting arcs for f2 theta = np.linspace(0, np.pi, 100) for i, segment in enumerate(f2): start_angle = np.degrees(np.arccos( 2 * segment[0] / 100 - 1 )) end_angle = np.degrees(np.arccos(2 * segment[1] / 100 - 1)) arc_center = (start_angle + end_angle) / 2 start_x = np.cos(np.radians(start_angle)) * R + R start_y = np.sin(np.radians(start_angle)) * R + D ax.plot(start_x, start_y, 'o', color='black') end_x = np.cos(np.radians(end_angle)) * R + R end_y = np.sin(np.radians(end_angle)) * R + D ax.plot(end_x, end_y, 'o', color='red') ax.plot(np.cos(theta) * R + R, np.sin(theta) * R + D, color='gray') # Arrows if i == 0: ax.annotate('', xy=(f1[i][0], W/2), xytext=(start_x, start_y), arrowprops=dict(facecolor=colors[i], arrowstyle='-')) elif i == len(f1) - 1: ax.annotate('', xy=(f1[i-1][1], W/2), xytext=(start_x, start_y), arrowprops=dict(facecolor=colors[i], arrowstyle='-')) ax.annotate('', xy=(f1[i][1], W/2), xytext=(end_x, end_y), arrowprops=dict(facecolor=colors[i], arrowstyle='-')) elif i > 0: ax.annotate('', xy=(f1[i-1][1], W/2), xytext=(start_x, start_y), arrowprops=dict(facecolor=colors[i], arrowstyle='-')) # Removing y-axis ax.set_yticks([]) ax.set_ylabel('') # Setting aspect ratio ax.set_aspect('equal') # Set xlim to enlarge the graph towards -x ax.set_xlim(-1 * arc_width, None) plt.title('Range Mapping: Bar to Circle') plt.show()
Example at colab
Thanks for the suggestion — but this is probably a little bit too narrow to have as a plotting function in seaborn.
I want to plot mappings between two ranges. For instance, x is the independent variable and f1, f2 corresponding ranges:
My basic implementation with pyplot for two cases (bar to bar, bar to circle)
Example at colab