Рубрики
Без рубрики

WxPython: Pyplot – Графики с Python

Получите практические, реальные навыки Python на наших ресурсах и пути

Автор оригинала: Mike Driscoll.

Некоторые люди учатся сделать это, другие лучше с визуальными раздражителями. По крайней мере, вот что нам говорят. Таким образом, в духе того, что мы учили, мы собираемся взглянуть на визуальную половину уравнения и посмотреть, как мы можем сделать графики с Wxpython. Вы можете не знать это, но WxPython включает в себя виджет только для этой цели. Это имя pyplot. Pyplot отлично подходит для простых участков, и это слишком быстро! Если вам нужно странно или сложно замышлять, то вы захотите использовать вместо этого matplotlib. К счастью, Wxpython и Matplotlib играют хорошо друг с другом, но мы не будем смотреть на Matplotlib в этой статье.

Начало работы (с гистограммой!)

Если вы посмотрите на Plot.py Файл в распределении WXPYPHON Вы обнаружите, что Pyplot требует числовых, Nummeray или Numpy (в обратном порядке), поэтому убедитесь, что у вас есть один из тех, которые установлены, чтобы иметь возможность использовать этот виджет. Конечно, WXPYPHON также требуется, но вы знали, что правильно?

Во всяком случае, в нижней части этого файла Python есть простое демо, которое показывает, как делать различные графики с Pyplot. Давайте возьмем часть этого кода и посмотрим, сможем ли мы понять это.

import wx
from wx.lib.plot import PolyLine, PlotCanvas, PlotGraphics

#----------------------------------------------------------------------
def drawBarGraph():
    # Bar graph
    points1=[(1,0), (1,10)]
    line1 = PolyLine(points1, colour='green', legend='Feb.', width=10)
    points1g=[(2,0), (2,4)]
    line1g = PolyLine(points1g, colour='red', legend='Mar.', width=10)
    points1b=[(3,0), (3,6)]
    line1b = PolyLine(points1b, colour='blue', legend='Apr.', width=10)

    points2=[(4,0), (4,12)]
    line2 = PolyLine(points2, colour='Yellow', legend='May', width=10)
    points2g=[(5,0), (5,8)]
    line2g = PolyLine(points2g, colour='orange', legend='June', width=10)
    points2b=[(6,0), (6,4)]
    line2b = PolyLine(points2b, colour='brown', legend='July', width=10)

    return PlotGraphics([line1, line1g, line1b, line2, line2g, line2b],
                        "Bar Graph - (Turn on Grid, Legend)", "Months", 
                        "Number of Students")

########################################################################
class MyGraph(wx.Frame):

    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          'My First Plot (to take over the world!)')

        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        
        # create some sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        checkSizer = wx.BoxSizer(wx.HORIZONTAL)
        
        # create the widgets
        self.canvas = PlotCanvas(panel)
        self.canvas.Draw(drawBarGraph())
        toggleGrid = wx.CheckBox(panel, label="Show Grid")
        toggleGrid.Bind(wx.EVT_CHECKBOX, self.onToggleGrid)
        toggleLegend = wx.CheckBox(panel, label="Show Legend")
        toggleLegend.Bind(wx.EVT_CHECKBOX, self.onToggleLegend)
                
        # layout the widgets
        mainSizer.Add(self.canvas, 1, wx.EXPAND)
        checkSizer.Add(toggleGrid, 0, wx.ALL, 5)
        checkSizer.Add(toggleLegend, 0, wx.ALL, 5)
        mainSizer.Add(checkSizer)
        panel.SetSizer(mainSizer)
        
    #----------------------------------------------------------------------
    def onToggleGrid(self, event):
        """"""
        self.canvas.SetEnableGrid(event.IsChecked())
        
    #----------------------------------------------------------------------
    def onToggleLegend(self, event):
        """"""
        self.canvas.SetEnableLegend(event.IsChecked())
        
if __name__ == '__main__':
    app = wx.App(False)
    frame = MyGraph()
    frame.Show()
    app.MainLoop()

ДЕРЕВОЧНЫЙГРАФ Функция вытащена непосредственно из файла plot.py, который был упомянут ранее. Для этого примера имя функции было изменено с «_DRAW6Objects» на «DrawBargraph», чтобы упростить код. Давайте посмотрим на это. Точки представляют собой точки на графике: [(x1, y1), (x2, y2)]. Они говорят Pyplot, где построить через Polyline метод. Как видите, Polyline принимает список кортежей точек графов, а также, необязательно, цвет, легенды, ширина и стиль (не показаны). Мы создаем серию полилиний, а затем добавляем их в Плотрография пример. Первый метод плотгрофики представляет собой список полилиний (или других объектов Polyxxx), заголовок, XLABEL и YLABEL. Мы возвращаем объект Plotgraphics обратно в абонент, который находится в нашем классе WXPYPHON.

Теперь мы обращаем наше внимание на этот класс, который имеет блаженную название MyGraph. Первые несколько строк довольно знакомы, если вы использовали WXPYPHON раньше, поэтому давайте пропустим те и прыгнувшими к разделу создания виджета. Здесь мы видим, как создать Plotcanvas только с простой WX.Panel в качестве родителя. Чтобы нарисовать гистограмма, мы называем наш объект Canvas Рисовать Способ, проходящие в объекте сюжета, который был возвращен из функции лестбарграфа. Не стесняйтесь перечитать, что столько раз, сколько нужно, чтобы понять, что происходит, прежде чем продолжить.

Вы готовы? Тогда давайте продолжим! После того, как мы нарисуем гистограмму, мы создаем пару флажки, чтобы позволить нам переключить сетку и легенду графика. Затем мы выкладываем виджеты на раме. Методы Feecure Box являются красивыми самоснабжениями, поэтому вы можете понять их самостоятельно. Подсказка: ischecked () Возвращает логию.

Графичность с использованием сохраненных данных

Обычно вы хотите прочитать данные из сохраненного файла, базы данных или веб-сервиса, а не с помощью жестких данных. Здесь мы посмотрим на использование некоторых сохраненных данных для создания графика. Вот данные, которые мы будем использовать (вы, вероятно, захотите скачать архивы внизу статьи):

# CDT, Max Temperff, средняя температурар, мин. Температура, Max Dew Pointf, означают точку зрения, мин DEWPOINTF, MAX влажность, средняя влажность, мин влажность, макс. Давление на уровне моря, средний давление на уровне моря, мин. , Мин видимости, максимальный ветер спинмп, средняя скорость ветра, MAX Gust Speedmph, осаждение, облачность, события 2010-9-19 56,52,47,55,49,44100 97,93,30,21,30,17,30,1,10,51,19,19,9,20,0.34,8, дождь-гроза 2010-9-20 88,725-9-20 88,7256,71,62,555100773,46,30.10,29,94,29,77,10,6,0,25,12,32, т, 4, туманный дождь 2010-9-21,75,70,64,66,64,66393,83,73,29,89,29,83,73,29,89,29,83,29,75,89,29,83,29,75,10,70,6,022,7,30,12,79,5, туман Гроза 2010-9-22,75,70,64,66,6463,10096,66,6,629,9699,86,00,29,996,29,86,10,5,1,15,4, 0,26,8, дождь 0,481: 1.

Первая строка – это веб-сайт, второй рассказывает нам, что следуют строки с ограниченными запятыми. Последние четыре строки являются простыми данными с каким-то нежелательным HTML в конце каждого Лин. Последняя строка также что-то захочешь игнорировать. Давайте создадим какой-код, чтобы на самом деле построить эти данные!

import wx
from wx.lib.plot import PolyLine, PlotCanvas, PlotGraphics

class MyGraph(wx.Frame):

    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          'Plotting File Data')

        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        self.canvas = PlotCanvas(panel)
        self.canvas.Draw(self.createPlotGraphics())
        
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.canvas, 1, wx.EXPAND)
        panel.SetSizer(sizer)
        
    #----------------------------------------------------------------------
    def readFile(self):
        """"""
        # normally you would want to pass a file path in, NOT hard code it!
        f = open("data.txt")
        # skip the first two lines of text in the file
        data = f.readlines()[2:-1]
        temps = []
        for line in data:
            parts = line.split(",")
            date = parts[0].split("-")
            day = date[2]
            points = [(day, parts[3]), (day, parts[1])]
            temps.append(points)
        return temps
        
    #----------------------------------------------------------------------
    def createPlotGraphics(self):
        """"""
        temps = self.readFile()
        lines = []
        for temp in temps:
            tempInt = int(temp[1][1])
            if tempInt < 60:
                color = "blue"
            elif tempInt >=60 and tempInt <= 75:
                color = "orange"
            else:
                color = "red"
            lines.append(PolyLine(temp, colour=color, width=10))
            
        return PlotGraphics(lines, "Bar Graph of Temperatures", 
                            "Days", "Temperatures")
            
if __name__ == '__main__':
    app = wx.App(False)
    frame = MyGraph()
    frame.Show()
    app.MainLoop()

Вы можете узнать этот код? Ну, если вы не можете (или не хотите), то вы можете прочитать все об этом сейчас! Как и в нашем предыдущем примере, мы импортируем несколько вещей и создаем wx.frame с панелью и Plotcanvas. У нас простой readfile Метод и createplotgraphics Способ тоже. Эти два метода – это то, на что мы будем сосредоточиться.

Метод readfile вызывается методом createplotgraphics. Все это делает, читается файл. Для этого примера у нас есть «путь» к файлу в жестком законе. То, что вы обычно хотите сделать, это использовать какой-то браузер файлов для загрузки файла, но мы собираемся в супер-простой маршрут. Когда мы читаем строки из файла, мы пропускаем первые два с помощью следующего синтаксиса:

data = f.readlines()[2:-1]

Что это делает, пропускает первые две строки в файле и прочитать до конца, минус одна строка. Делаю это таким образом, мы пропускаем мусор в начале и конец. Не питон круто? Далее мы создаем простое «для цикла», чтобы вытащить данные, которые мы хотим, что просто день, низкая и высокая температура. Остальные мы просто выбрасываем.

В методе CreatePlotgraphics мы принимаем список темп, возвращаемых из метода readFile и цикл над теми, создавая новый список полилиний. Мы используем некоторые «если утверждения», чтобы решить, какого цвета сделать каждый бар в гистограмме. Наконец, мы вкладываем все полилины в экземпляр сюжета и вернемся к тому, что вызывается в методе __init__. Это все, что есть к этому!

Уместный участок с тысячами точек

Теперь мы собираемся посмотреть, как создать точку сюжета с 25 000 участков! Этот также из демо. Вот код:

import numpy.oldnumeric as _Numeric
import wx
from wx.lib.plot import PlotCanvas, PlotGraphics, PolyLine, PolyMarker

#----------------------------------------------------------------------
def drawLinePlot():
    # 25,000 point line
    data1 = _Numeric.arange(5e5,1e6,10)
    data1.shape = (25000, 2)
    line1 = PolyLine(data1, legend='Wide Line', colour='green', width=5)

    # A few more points...
    markers2 = PolyMarker(data1, legend='Square', colour='blue',
                          marker='square')
    return PlotGraphics([line1, markers2], "25,000 Points", "Value X", "")


########################################################################
class MyGraph(wx.Frame):

    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          'It Looks Like a Line Graph!')

        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        
        # create some sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        checkSizer = wx.BoxSizer(wx.HORIZONTAL)
        
        # create the widgets
        self.canvas = PlotCanvas(panel)
        self.canvas.Draw(drawLinePlot())
        toggleGrid = wx.CheckBox(panel, label="Show Grid")
        toggleGrid.Bind(wx.EVT_CHECKBOX, self.onToggleGrid)
        toggleLegend = wx.CheckBox(panel, label="Show Legend")
        toggleLegend.Bind(wx.EVT_CHECKBOX, self.onToggleLegend)
                
        # layout the widgets
        mainSizer.Add(self.canvas, 1, wx.EXPAND)
        checkSizer.Add(toggleGrid, 0, wx.ALL, 5)
        checkSizer.Add(toggleLegend, 0, wx.ALL, 5)
        mainSizer.Add(checkSizer)
        panel.SetSizer(mainSizer)
        
    #----------------------------------------------------------------------
    def onToggleGrid(self, event):
        """"""
        self.canvas.SetEnableGrid(event.IsChecked())
        
    #----------------------------------------------------------------------
    def onToggleLegend(self, event):
        """"""
        self.canvas.SetEnableLegend(event.IsChecked())
        
if __name__ == '__main__':
    app = wx.App(False)
    frame = MyGraph()
    frame.Show()
    app.MainLoop()

Мы повторно используем большую часть кода WXPYPHON, который мы видели в нашем оригинальном примере, и просто называйте другую функцию здесь. DrawLeplot Функция довольно проста. Для этого примера мы используем Numpy для создания точек сюжета 25 000, а затем создать с ними полилинию. Если вы увеличите масштаб, вы увидите, что некоторые очки являются квадратом, а не раунд. Это то, для чего есть класс полимаркера. Он устанавливает стиль «маркера». Теперь мы готовы посмотреть наш следующий пример!

Создание синусоида/косина

В этом примере показано, как взять синус и косинус и график их. Это выглядит как горизонтальная двойная спираль. Во всяком случае, вот код:

import numpy.oldnumeric as _Numeric
import wx
from wx.lib.plot import PlotCanvas, PlotGraphics, PolyLine, PolyMarker

def drawSinCosWaves():
    # 100 points sin function, plotted as green circles
    data1 = 2.*_Numeric.pi*_Numeric.arange(200)/200.
    data1.shape = (100, 2)
    data1[:,1] = _Numeric.sin(data1[:,0])
    markers1 = PolyMarker(data1, legend='Green Markers', colour='green', marker='circle',size=1)

    # 50 points cos function, plotted as red line
    data1 = 2.*_Numeric.pi*_Numeric.arange(100)/100.
    data1.shape = (50,2)
    data1[:,1] = _Numeric.cos(data1[:,0])
    lines = PolyLine(data1, legend= 'Red Line', colour='red')

    # A few more points...
    pi = _Numeric.pi
    markers2 = PolyMarker([(0., 0.), (pi/4., 1.), (pi/2, 0.),
                          (3.*pi/4., -1)], legend='Cross Legend', colour='blue',
                          marker='cross')
    
    return PlotGraphics([markers1, lines, markers2],"Graph Title", "X Axis", "Y Axis")

########################################################################
class MyGraph(wx.Frame):

    #----------------------------------------------------------------------
    def __init__(self):
        wx.Frame.__init__(self, None, wx.ID_ANY, 
                          'Sin / Cos Plot')

        # Add a panel so it looks the correct on all platforms
        panel = wx.Panel(self, wx.ID_ANY)
        
        # create some sizers
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        checkSizer = wx.BoxSizer(wx.HORIZONTAL)
        
        # create the widgets
        self.canvas = PlotCanvas(panel)
        self.canvas.Draw(drawSinCosWaves())
        toggleGrid = wx.CheckBox(panel, label="Show Grid")
        toggleGrid.Bind(wx.EVT_CHECKBOX, self.onToggleGrid)
        toggleLegend = wx.CheckBox(panel, label="Show Legend")
        toggleLegend.Bind(wx.EVT_CHECKBOX, self.onToggleLegend)
                
        # layout the widgets
        mainSizer.Add(self.canvas, 1, wx.EXPAND)
        checkSizer.Add(toggleGrid, 0, wx.ALL, 5)
        checkSizer.Add(toggleLegend, 0, wx.ALL, 5)
        mainSizer.Add(checkSizer)
        panel.SetSizer(mainSizer)
        
    #----------------------------------------------------------------------
    def onToggleGrid(self, event):
        """"""
        self.canvas.SetEnableGrid(event.IsChecked())
        
    #----------------------------------------------------------------------
    def onToggleLegend(self, event):
        """"""
        self.canvas.SetEnableLegend(event.IsChecked())
        
if __name__ == '__main__':
    app = wx.App(False)
    frame = MyGraph()
    frame.Show()
    app.MainLoop()

Этот пример для математических гиков там. У меня довольно давно я не сделал тригонометрию или геометрии, поэтому я не буду объяснять уравнения здесь. Вы можете посмотреть на такую вещь с вашей любимой поисковой системой. Этот пример использует одну полилинию и два полимаркера для создания графика. Это в основном похоже на другие примеры, поэтому на самом деле нельзя сказать.

Обертывание

К настоящему времени вы должны быть более чем готовыми к выполнению графиков самостоятельно с WxPython. Если вы застряли, есть несколько других примеров в файле plot.py, а участники списка рассылки wxpython довольно дружелюбны и, вероятно, помогут вам, если вы спросите, хорошо. Дайте мне знать, если вы создадите что-нибудь круто!

Примечание. Код в этой статье был протестирован на Windows XP, Python 2.5, WXPYPHON 2.8.10.1

Дальнейшее чтение

  • Официальная документация для Pyplot.

Загрузки

  • PyPlot.zip
  • Pyplot.tar.tar.