2013-06-29 5 views
3

Я действительно борется с matplotlib, особенно с настройками оси. Моя цель состоит в том, чтобы настроить 6 подзаголовков на одном рисунке, которые отображают разные наборы данных, но имеют одинаковое количество меток.Шесть подзаговоров с таким же количеством xticklabels в matplotlib

Соответствующая часть моей исходный код выглядит следующим образом:

graph4.py:

# Import Matolotlib Modules # 
import matplotlib as mpl 
from matplotlib.figure import Figure 
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas 
from matplotlib import ticker 
import matplotlib.pyplot as plt 

mpl.rcParams['font.sans-serif']='Arial' #set font to arial 

# Import GTK Modules # 

import gtk 

#Import System Modules # 
import sys 

# Import Numpy Modules # 
from numpy import genfromtxt 
import numpy 

# Import Own Modules # 
import mysubplot as mysp 

class graph4(): 
    weekdays = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'] 

    def __init__(self, graphview): 
     #create new Figure 
     self.figure = Figure(figsize=(100,100), dpi=75) 

     #create six subplots within self.figure 
     self.subplot = [] 
     for j in range(6): 
      self.subplot.append(self.figure.add_subplot(321 + j)) 


     self.__conf_subplots__() #configure title, xlabel, ylabel and grid of all subplots 


     #to make it look better  
     self.figure.subplots_adjust(left=0.125, bottom=0.1, right=0.9, top=0.96, wspace=0.2, hspace=0.6)  

     #Matplotlib <-> GTK 
     self.canvas = FigureCanvas(self.figure) # a gtk.DrawingArea 
     self.canvas.set_flags(gtk.HAS_FOCUS|gtk.CAN_FOCUS) 
     self.canvas.grab_focus() 
     self.canvas.show() 
     graphview.pack_start(self.canvas, True, True) 


     #add labels and grid to all subplots 
     def __conf_subplots__(self): 
      index = 0 
      for i in self.subplot: 
       mysp.conf_subplot(i, 'Zeit', 'Menge', graph4.weekdays[index], True) 
       i.plot([], [], 'bo') #empty plot 
       index +=1 


     def plot(self, filename_list): 
      index = 0 
      for filename in filename_list: 
       data = genfromtxt(filename, delimiter=',') #load data from filename 
       if data.size != 0: #only if file isn't empty 
        if index <= len(self.subplot): #plot every file on a different subplot 
         mysp.plot(self.subplot[index],data[0:, 1], data[0:, 0]) 
         index +=1 


      self.canvas.draw() 


      def clear_plot(self): 
       #clear axis of all subplots 
       for i in self.subplot: 
        i.cla() 

       self.__conf_subplots__() 

mysubplot.py: (вспомогательный модуль)

# Import Matplotlib Modules 
from matplotlib.axes import Subplot 
import matplotlib.dates as md 
import matplotlib.pyplot as plt 

# Import Own Modules # 
import mytime as myt 

# Import Numpy Modules # 
import numpy as np 

def conf_subplot(subplot, xlabel, ylabel, title, grid): 
    if(xlabel != None): 
     subplot.set_xlabel(xlabel) 
    if(ylabel != None): 
     subplot.set_ylabel(ylabel) 
    if(title != None): 
     subplot.set_title(title) 
    subplot.grid(grid) 

    #rotate xaxis labels 
    plt.setp(subplot.get_xticklabels(), rotation=30, fontsize=12) 

    #display date on xaxis 
    subplot.xaxis.set_major_formatter(md.DateFormatter('%H:%M:%S'))  
    subplot.xaxis_date() 


def plot(subplot, x, y): 
    subplot.plot(x, y, 'bo') 

Я думаю, лучший способ объяснить, что пойдет не так, с использованием скриншотов. После того, как я начинаю мое приложение, все выглядит хорошо:

http://i.imgur.com/SqwaPyG.png

Если я дважды щелкнуть «Week'-вход слева, метод clear_plot() в graph4.py вызывается для сброса всех делянок. Затем список имен файлов передается методу plot() в graph4.py. Метод plot() открывает каждый файл и отображает каждый набор данных на другом подзаголовке. Поэтому после того, как я дважды щелкните запись, это выглядит следующим образом:

enter image description here

Как вы можете видеть, каждый сюжетные имеет различное количество XTICK этикеток, который выглядит очень некрасиво со мной. Поэтому я ищу решение, чтобы улучшить это. Мой первый подход состоял в том, чтобы вручную установить метки метки с помощью xaxis.set_ticklabels(), так что каждый подзаголовок имеет такое же количество меток. Однако, как ни странно, это работает только на некоторых наборах данных, и я действительно не знаю, почему. В некоторых наборах данных все работает отлично, а на других наборах данных matplotlib в основном делает то, что хочет, и отображает метки xaxis, которые я не указывал. Я также попробовал FixedLocator(), но я получил тот же результат. На некоторых наборах данных он работает, а на других, matplotlib использует другое количество ярлыков xtick.

Что я делаю неправильно?

Edit:

Как @sgpc предложил, я пытался использовать pyplot. Мой исходный код теперь выглядит следующим образом:

import matplotlib as mpl 
import matplotlib.pyplot as plt 
from matplotlib.backends.backend_gtkagg import FigureCanvasGTKAgg as FigureCanvas 
import matplotlib.dates as md 

mpl.rcParams['font.sans-serif']='Arial' #set font to arial 

import gtk 
import sys 

# Import Numpy Modules # 
from numpy import genfromtxt 
import numpy 

# Import Own Modules # 
import mysubplot as mysp 

class graph2(): 
    weekdays = ['Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'] 

    def __init__(self, graphview): 
     self.figure, temp = plt.subplots(ncols=2, nrows=3, sharex = True) 

     #2d array -> list 
     self.axes = [ y for x in temp for y in x] 

     #axis: date 
     for i in self.axes: 
      i.xaxis.set_major_formatter(md.DateFormatter('%H:%M:%S')) 
      i.xaxis_date() 

     #make space and rotate xtick labels 
     self.figure.autofmt_xdate() 

     #Matplotlib <-> GTK 
     self.canvas = FigureCanvas(self.figure) # a gtk.DrawingArea 
     self.canvas.set_flags(gtk.HAS_FOCUS|gtk.CAN_FOCUS) 
     self.canvas.grab_focus() 
     self.canvas.show() 
     graphview.pack_start(self.canvas, True, True) 

    def plot(self, filename_list): 
     index = 0 
     for filename in filename_list: 
      data = genfromtxt(filename, delimiter=',') #get dataset 
      if data.size != 0: #only if file isn't empty 
       if index < len(self.axes): #print each dataset on a different subplot 
        self.axes[index].plot(data[0:, 1], data[0:, 0], 'bo') 
        index +=1 

     self.canvas.draw() 

    #not yet implemented 
    def clear_plot(self): 
     pass 

Если я сюжет некоторые наборы данных, я получаю следующий вывод: http://i.imgur.com/3ngYTNr.png (извините, я до сих пор не имеют достаточной репутации возможность размещения фотографий)

Кроме того, я я действительно не уверен, что разделение оси x является действительно хорошей идеей, потому что возможно, что значения x различаются в каждом подзаголовке (например: в первом подзаголовке значения x варьируются от 8:00 до 11: 00am, а во втором подзадаче значения x варьируются от 19:00 до 21:00).

Если я избавлюсь от sharex = True, я получаю следующий результат:

http://i.imgur.com/rxHeSyJ.png (извините, я до сих пор не имеют достаточной репутации возможность размещения фотографий)

Как вы можете видеть, вывод выглядит теперь лучше. Однако теперь метки на х-осях не обновляются. Я предполагаю, что это потому, что последние suplots пусты.

Моя следующая попытка состояла в том, чтобы использовать ось для каждого подзаголовка. Поэтому я сделал это изменения:

for i in self.axes: 
    plt.setp(i.get_xticklabels(), visible=True, rotation = 30) #<-- I added this line... 
    i.xaxis.set_major_formatter(md.DateFormatter('%H:%M:%S')) 
    i.xaxis_date() 

#self.figure.autofmt_xdate() #<--changed this line 
self.figure.subplots_adjust(left=0.125, bottom=0.1, right=0.9, top=0.96, wspace=0.2, hspace=0.6) #<-- and added this line 

Теперь я получаю следующий результат:

i.imgur.com/TmA1goE.png (извините, я до сих пор не имеют достаточной репутации возможность размещения фотографий)

Так что с этой попыткой я в основном борюсь с той же проблемой, что и с Figure() и add_subplot().

Я действительно не знаю, что еще я мог бы попытаться заставить его работать ...

ответ

0

Я настоятельно рекомендую вам использовать pyplot.subplots() с sharex=True:

fig, axes = subplots(ncols=2, nrows=3, sharex= True) 

Тогда доступ к каждому топоры с помощью:

ax = axes[i,j] 

И вы можете построить делать:

ax.plot(...) 

Чтобы контролировать количество тиков для каждого AxesSubplot вы можете использовать:

ax.locator_params(axis='x', nbins=6) 

OBS: axis может быть 'x', 'y' или 'both'

+0

nordev: Спасибо за добавление фотографии! @sgpc: Спасибо, я попробую. Вначале я использовал Figure() вместе с add_subplot(), потому что я думал, что невозможно встраивать графический объект в окно GTK. По крайней мере, я подумал, что я прочитал его где-то в документации matplotlib. Тем не менее, я не совсем уверен в этом сейчас ... Я попробую! – user2494129

+0

ОК, просто дайте мне знать, если вам нужна помощь ... Я использую 'subplots' много, и это работает очень хорошо ... –

+0

Я попытался использовать pyplot, но столкнулся с некоторыми проблемами (см. Мое редактирование в первом сообщении). У вас есть идея, что еще я мог бы попытаться заставить его работать? – user2494129