несколько осей в matplotlib с разными масштабами
Как можно реализовать несколько шкал в Matplotlib? Я не говорю о первичной и вторичной оси, построенной против одной и той же оси x, но что-то вроде многих тенденций, которые имеют разные масштабы, построенные по одной и той же оси y, и которые могут быть идентифицированы по их цветам.
например, если у меня есть trend1 ([0,1,2,3,4]) и trend2 ([5000,6000,7000,8000,9000]) чтобы построить график против времени и чтобы два тренда были разных цветов и по оси Y, разных масштабов, как я могу это сделать с помощью Matplotlib?
когда я заглянул в Matplotlib, они говорят, что у них сейчас этого нет, хотя это определенно в их списке желаний, есть ли способ сделать это?
есть ли другие инструменты построения графиков для python, которые могут это сделать?
4 ответов:
Если я понимаю вопрос, вы можете заинтересоваться в галерее Matplotlib.
комментарий Янна выше дает аналогичный пример.
Edit-ссылка выше исправлена. Соответствующий код скопирован из галереи Matplotlib:
from mpl_toolkits.axes_grid1 import host_subplot import mpl_toolkits.axisartist as AA import matplotlib.pyplot as plt host = host_subplot(111, axes_class=AA.Axes) plt.subplots_adjust(right=0.75) par1 = host.twinx() par2 = host.twinx() offset = 60 new_fixed_axis = par2.get_grid_helper().new_fixed_axis par2.axis["right"] = new_fixed_axis(loc="right", axes=par2, offset=(offset, 0)) par2.axis["right"].toggle(all=True) host.set_xlim(0, 2) host.set_ylim(0, 2) host.set_xlabel("Distance") host.set_ylabel("Density") par1.set_ylabel("Temperature") par2.set_ylabel("Velocity") p1, = host.plot([0, 1, 2], [0, 1, 2], label="Density") p2, = par1.plot([0, 1, 2], [0, 3, 2], label="Temperature") p3, = par2.plot([0, 1, 2], [50, 30, 15], label="Velocity") par1.set_ylim(0, 4) par2.set_ylim(1, 65) host.legend() host.axis["left"].label.set_color(p1.get_color()) par1.axis["right"].label.set_color(p2.get_color()) par2.axis["right"].label.set_color(p3.get_color()) plt.draw() plt.show() #plt.savefig("Test")
Если вы хотите сделать очень быстрые графики со вторичной осью Y, то есть гораздо более простой способ, используя функцию оболочки Pandas и всего 2 строки кода. Просто постройте свой первый столбец, а затем постройте второй, но с параметром
secondary_y=True, например:df.A.plot(label="Points", legend=True) df.B.plot(secondary_y=True, label="Comments", legend=True)это будет выглядеть примерно так:
Вы можете сделать еще несколько вещей. Взгляните на панды замышляют док.
С ответ Стива Tjoa всегда всплывает первым и в основном одиноко, когда я ищу несколько y-осей в Google, я решил добавить немного измененную версию своего ответа. Это подход от это matplotlib пример.
причины:
- его модули иногда терпят неудачу для меня в неизвестных обстоятельствах и загадочных ошибках стажера.
- я не люблю загружать экзотические модули я не знаю (
mpl_toolkits.axisartist,mpl_toolkits.axes_grid1).- код, приведенный ниже, содержит больше явно команды проблем люди часто спотыкаются (например, одна легенда для нескольких осей, используя viridis,...), а не неявное поведение.
import matplotlib.pyplot as plt fig = plt.figure() host = fig.add_subplot(111) par1 = host.twinx() par2 = host.twinx() host.set_xlim(0, 2) host.set_ylim(0, 2) par1.set_ylim(0, 4) par2.set_ylim(1, 65) host.set_xlabel("Distance") host.set_ylabel("Density") par1.set_ylabel("Temperature") par2.set_ylabel("Velocity") color1 = plt.cm.viridis(0) color2 = plt.cm.viridis(0.5) color3 = plt.cm.viridis(.9) p1, = host.plot([0, 1, 2], [0, 1, 2], color=color1,label="Density") p2, = par1.plot([0, 1, 2], [0, 3, 2], color=color2, label="Temperature") p3, = par2.plot([0, 1, 2], [50, 30, 15], color=color3, label="Velocity") lns = [p1, p2, p3] host.legend(handles=lns, loc='best') # right, left, top, bottom par2.spines['right'].set_position(('outward', 60)) # no x-ticks par2.xaxis.set_ticks([]) # Sometimes handy, same for xaxis #par2.yaxis.set_ticks_position('right') host.yaxis.label.set_color(p1.get_color()) par1.yaxis.label.set_color(p2.get_color()) par2.yaxis.label.set_color(p3.get_color()) plt.savefig("pyplot_multiple_y-axis.png", bbox_inches='tight')
Bootstrapping что-то быстро для отображения нескольких осей y, разделяющих ось x с помощью @Джо-Кингтон ответ:
# d = Pandas Dataframe, # ys = [ [cols in the same y], [cols in the same y], [cols in the same y], .. ] def chart(d,ys): from itertools import cycle fig, ax = plt.subplots() axes = [ax] for y in ys[1:]: # Twin the x-axis twice to make independent y-axes. axes.append(ax.twinx()) extra_ys = len(axes[2:]) # Make some space on the right side for the extra y-axes. if extra_ys>0: temp = 0.85 if extra_ys<=2: temp = 0.75 elif extra_ys<=4: temp = 0.6 if extra_ys>5: print 'you are being ridiculous' fig.subplots_adjust(right=temp) right_additive = (0.98-temp)/float(extra_ys) # Move the last y-axis spine over to the right by x% of the width of the axes i = 1. for ax in axes[2:]: ax.spines['right'].set_position(('axes', 1.+right_additive*i)) ax.set_frame_on(True) ax.patch.set_visible(False) ax.yaxis.set_major_formatter(matplotlib.ticker.OldScalarFormatter()) i +=1. # To make the border of the right-most axis visible, we need to turn the frame # on. This hides the other plots, however, so we need to turn its fill off. cols = [] lines = [] line_styles = cycle(['-','-','-', '--', '-.', ':', '.', ',', 'o', 'v', '^', '<', '>', '1', '2', '3', '4', 's', 'p', '*', 'h', 'H', '+', 'x', 'D', 'd', '|', '_']) colors = cycle(matplotlib.rcParams['axes.color_cycle']) for ax,y in zip(axes,ys): ls=line_styles.next() if len(y)==1: col = y[0] cols.append(col) color = colors.next() lines.append(ax.plot(d[col],linestyle =ls,label = col,color=color)) ax.set_ylabel(col,color=color) #ax.tick_params(axis='y', colors=color) ax.spines['right'].set_color(color) else: for col in y: color = colors.next() lines.append(ax.plot(d[col],linestyle =ls,label = col,color=color)) cols.append(col) ax.set_ylabel(', '.join(y)) #ax.tick_params(axis='y') axes[0].set_xlabel(d.index.name) lns = lines[0] for l in lines[1:]: lns +=l labs = [l.get_label() for l in lns] axes[0].legend(lns, labs, loc=0) plt.show()




Comments