Страницы

Поиск по вопросам

Показаны сообщения с ярлыком график. Показать все сообщения
Показаны сообщения с ярлыком график. Показать все сообщения

понедельник, 2 марта 2020 г.

Как лучше реализовать масштабирование свеч на графике

#c_sharp #wpf #график #wpf_canvas


Нарисовал свой график на панели Canvas.
Как его рисовал я - Есть массив всех свеч, и я вывожу на панель лишь видимый диапазон
свеч, т.е. если сдвинуть график в сторону, я с каждой новой свечой рассчитаю новый
диапазон видимых свеч, очищаю Canvas.Children и данный список выведу на график, добавив
в Canvas.Children. При таком варианте я могу спокойно настраивать масштаб, при новом
расчете я нахожу максимум и минимум свеч и заношу рассчитываю высоту относительно этого.
Но данный способ слишком долгий для расчетов. И в итоге логичнее уже на графике хранить
сразу все свечи. Но вот проблема заключается тогда в видимом диапазоне. Т.е. надо в
массиве Canvas.Childern найти нужные свечи и поменять их значения Y и X, значения длины
прямоугольников и линий, которые идут вверх и вниз от них. Но будет ли это лаконичным?
На сайтах это всё происходит мгновенно, как ни крути. Может кто подсказать пожалуйста,
как лучше реализовать это? 2 картинки, с любого сайта и моей программы.


    


Ответы

Ответ 1



Смотрите, как можно сделать это с помощью трансформаций. Я буду выводить коллекцию прямоугольников, для вывода буду использовать ItemsControl, у которого в качестве ItemsPanel будет установлен Canvas. ItemsControl я оберну в Border, чтобы просто обозначить границы графика, ну и потом он еще сыграет свою небольшую роль. Также я размещу 2 кнопки для сдвига "окна" просмотра графика:

Рисование графиков на PHP

#php #графика #график


Как можно рисовать графики в PHP коде? Мне надо, чтобы выглядело примерно так:


    


Ответы

Ответ 1



Здравствуйте! Очень увлёкся Вашим вопросом, и смог добиться результатов. Получилось похоже на ваш график. Вот код с комментариями:

пятница, 14 февраля 2020 г.

Метод реализации графического интерфейса

#c_sharp #wpf #winforms #график




Необходимо будет сделать подобную вещь в своей программе на c# Windows Forms, возможно
и WPF. Из чего лучше всего сделать такой график? На нем нужно будет и многое другое
вырисовывать, но главное это основные свечи(красные, зеленые). Как мысль, самая банальная,
сделать координаты и рисовать по ним прямоугольники с линиями сверху и снизу. А при
масштабировании вырисовывать другие, более мелкие или большие. Но, может быть, есть
более лаконичное решение данной задачи? 
    


Ответы

Ответ 1



Ваш рисунок очень похож на Candlestick chart, название которого иногда переводят как японские свечи. Практически в каждой библиотеки для построения графиков такой тип тоже реализован, поэтому в первую очередь стоит рассмотреть готовые варианты прежде чем изобретать собственный велосипед. Пример того, как может выглядеть такой график нарисованный при помощи библиотеки OxyPlot Подчеркну, что кроме цвета фона использовались настройки по умолчанию, так как не ставил перед собой цели добиться соответствия с приведенным изображением. Данные получены случайным образом, по примеру из репозитория. Не буду копировать оттуда пример, но переведу его реализацию на F# для более наглядной демонстрации типов и методов библиотеки let candleStickSeries() = let model = PlotModel(Title = "", LegendSymbolLength = 24.0 ) let s1 = new CandleStickSeries(Title = "", Color = OxyColors.Black) let r = Random() Seq.initInfinite (fun _ -> r.NextDouble()) |> Seq.scan(fun price a -> price + a + 0.1) 100.0 |> Seq.indexed |> Seq.map (fun (i, price) -> let high = price + 10.0 + (r.NextDouble() * 10.0) let low = price - (10.0 + (r.NextDouble() * 10.0)) let open' = low + (r.NextDouble() * (high - low)) let close = low + (r.NextDouble() * (high - low)) new HighLowItem(float i, high, low, open', close)) |> Seq.take 30 |> Seq.iter s1.Items.Add model.Series.Add(s1) model.Axes.Add(new LinearAxis(Position = AxisPosition.Left, MaximumPadding = 0.3, MinimumPadding = 0.3 )) model.Axes.Add(new LinearAxis(Position = AxisPosition.Bottom, MaximumPadding = 0.03, MinimumPadding = 0.03 )) model Если хотите добиться полного (или почти полного совпадения), то советую разбить вопросы на несколько небольших и задать их по метке выбранной библиотеки.

пятница, 7 февраля 2020 г.

Построить график c#

#c_sharp #winforms #график


Добрый день, подскажите пожалуйста, как построить график многочлена :
сам многочлен p(x)=An*X^n + An-1*X^n-1+...+A1X+A0

 int[] array= new int[10];
int i, num, power;
float x;

num=4;
x=1;

array[0] = 3;
array[1] = -5;
array[2] = 6;
array[3] = 8;
array[4] = -9;

power = num;

double k = 0;

for (i = 0; i <= num; i++)
{
    k += Math.Pow(x, power--) * array[i];
 //   richTextBox1.AppendText(Convert.ToString(k) +"\n");

}


как щас построить график ?
    


Ответы

Ответ 1



Для начала вам будет достаточно стандартного класса Chart, хотя есть и сторонние компоненты для построения красивых графиков, но мне кажется, что сначала лучше разобраться со стандартным контролом. В документации на MSDN есть довольно подробный Tutorial. Основные моменты покажу в коде, подробности в официальной документации. class ChartForm : Form { public ChartForm() { //создаем элемент Chart Chart myChart = new Chart(); //кладем его на форму и растягиваем на все окно. myChart.Parent = this; myChart.Dock = DockStyle.Fill; //добавляем в Chart область для рисования графиков, их может быть //много, поэтому даем ей имя. myChart.ChartAreas.Add(new ChartArea("Math functions")); //Создаем и настраиваем набор точек для рисования графика, в том //не забыв указать имя области на которой хотим отобразить этот //набор точек. Series mySeriesOfPoint = new Series("Sinus"); mySeriesOfPoint.ChartType = SeriesChartType.Line; mySeriesOfPoint.ChartArea = "Math functions"; for (double x = -Math.PI; x <= Math.PI; x += Math.PI / 10.0) { mySeriesOfPoint.Points.AddXY(x, Math.Sin(x)); } //Добавляем созданный набор точек в Chart myChart.Series.Add(mySeriesOfPoint); } } Вот собственно минимум кода для рисования графика на форме. Здесь не приведены ни настройки осей координат и сетки, ни другие графические рюшечки которые поддерживает данный контрол, т.к. примеры применения практически всех возможностей этого контрола есть в официальной документации, ссылка выше. Дополнение: Вам нужно вычисление многочлена вынести в отдельную функцию. Это можно сделать например так double Polynom(double x, double[] coefficients) { double y = 0.0; double currentX = 1.0; for(int i = 0; i

среда, 22 января 2020 г.

Python matplotlib Построение гиперболы

#python #график #matplotlib


Добрый день! Хочу при помощи matplotlib построить, например, гиперболу. Есть следующий код:

import matplotlib.pyplot as plt
import pylab, math
xmin = -200
xmax = 200
dx = 0.1

xlist = [float(x) for x in range(xmin,xmax)]
ylist = [float(1/x) for x in range(xmin,xmax)]


ax = plt.gca()
ax.spines['right'].set_color('none')
ax.spines['top'].set_color('none')
ax.xaxis.set_ticks_position('bottom')
ax.spines['bottom'].set_position(('data',0))
ax.yaxis.set_ticks_position('left')
ax.spines['left'].set_position(('data',0))
plt.grid(True)
plt.title('График функции ')
pylab.plot(xlist,ylist)
pylab.savefig('123.png')


Пример работы на картинке
Как видно, между двумя ветвями функции есть отрезок. Я знаю, что это связанно с тем,
что есть значение крайних точек ветвей, а плот их соединяет. Но это мне не нужно, мне
нужно получить нормальный график. Если бы этот график был всегда гиперболой, было бы
нормально. Но этим графиком может быть любой график с разрывом. Как избежать этого
отрезка? Видел способы, но там использовались дополнительные пакеты(numpy), я не хочу
тянуть их в этот код
[]
    


Ответы

Ответ 1



Для начала повторюсь, что matplotlib уже внутри себя использует numpy, так что избежать его не выйдет. Тем не менее, вот первая версия без numpy в основном коде: import matplotlib.pyplot as plt import decimal # Это замена np.arange def arange(start, stop, step): while start < stop: yield start start += decimal.Decimal(step) hyperbola = lambda x: 1 / x def asymptote_checker(argument, function): try: function(argument) return True except ZeroDivisionError: return False xmin = -20 xmax = 20 dx = 0.1 xlist = [round(x, 4) for x in arange(xmin, xmax, dx)] ylist = [hyperbola(x) if asymptote_checker(x, hyperbola) else float('nan') for x in xlist] plt.plot(xlist, ylist) plt.show() С numpy выйдет покороче: import matplotlib.pyplot as plt import decimal import numpy as np xmin = -20 xmax = 20 dx = 0.1 xlist = np.around(np.arange(xmin, xmax, dx), decimals=4) ylist = 1 / xlist plt.plot(xlist, ylist) plt.show() Пара общих важных моментов для обеих версий: числа в xlist вместо нуля могут внезапно превратиться в мусор типа 7.0485345e-13 или типа того, что выльется в огромное значение по оси Oy. Второй момент - matplotlib игнорирует (и не соединяет точки) числа типа +inf, -inf, NaN - их можно пометить руками, доверить это numpy или использовать numpy masked array.

пятница, 27 декабря 2019 г.

Xamarin график с AChartEngine

#android #c_sharp #xamarin #chart #график


Хочу нарисовать график, нашел бесплатную библиотеку AChartEngine. Однако демо который
там имеется реализован на java. Пытался импортировать этот проект в Android Studio,
но ругается на отсутствие gradle в проекте.

В примере встречается создание объектов интерфейса(что нельзя сделать в c#) и не
получается разобраться как происходит отрисовка самого графика. Понимаю, что рисуется
это в LinearLayout, но как это делается... 

Написал Main.axml по этому примеру

Main.axml



    
    
        
        
        
        
        


Ответы

Ответ 1



Давно пользовался этой библиотекой, насколько помню, следующий шаг должен быть: var view = new GraphicalView(context, lineChart) Т.е. создать view на базе графика и как обычно вставить его в разметку. Добавлено А это не этот же компонент, уже адаптированный под Xamarin? https://components.xamarin.com/view/achartengine

понедельник, 9 декабря 2019 г.

Редактор графиков на Qt 4.8

#cpp #qt #график


Я делаю график на Qt. Пока на этапе строительства сетки. Все графические элементы
рисую с помощью графического представления и сцены.

Помогите корректно построить сетку, чтобы убрать вот эти «обрывки клеток» (Простите
за кривое выделение, но я думаю, видно, что у границ графика неполные клетки). 

То есть программа делит сцену на nXn клеток, но полных клеток (n-1)Х(n-1), остальное
идет на «обрывки» у границ графика. 



Сетку строю так:

 int n =10; 
// Окантовка графика
graphicsScene->addRect(2*n,0,graphicsScene->width()-2*n-10,graphicsScene->height()-2*n);

// Отступы сетки

int gdx = graphicsScene->width()/n;
int gdy = graphicsScene->height()/n;

// Строим сетку
for (int i = 1; iaddLine(QLineF((0), (graphicsScene->width()-gdx*i),(graphicsScene->width()),
(graphicsScene->height()-gdx*i)), QPen ( Qt::gray, 1));
// Вертикальные линии
    graphicsScene->addLine(QLineF(graphicsScene->height()-gdy*i,0,(graphicsScene->width()-gdy*i),
graphicsScene->width()-n), QPen ( Qt::gray, 1));
};
// Переменные графика
xmin = 0.0;
xmax = n;
dx = 0.05;

// Надписи на ОХ
for (int i =2; iaddText(QString::number((xmin + (i-1)*dx*10)))->setPos((graphicsScene->width()/n)*i-graphicsScene->width()/pow(n,3),graphicsScene->height()-2*n);
   }
   X = new QGraphicsTextItem ("X", 0,0);
   X->setPos (graphicsScene->width()-n, graphicsScene->height()-2*n);
   graphicsScene->addItem(X);

ZeroX = new QGraphicsTextItem ("0", 0,0);
ZeroX->setPos (2*n, graphicsScene->height()-2*n);

graphicsScene->addItem(ZeroX);

// Подписи на ОY

for (int i =0; iaddText(QString::number((n/2 - (i+1)*dx*10)))->setPos((n/5),(graphicsScene->width()/n)*i-graphicsScene->width()/pow(n,3)-n/2);

  }

 }


Вот скриншот в нормальном масштабе



Необходимо сделать такую сетку, чтобы можно было изменять ее масштаб, а также количество
клеток в ней. Также хотелось бы сделать возможность изменять стиль самого графика,
пунктирная, сплошная линия, цвета и т.д.

Ну и последнее сохранять и печатать график, как картинку.

Обновление от 01.06.2019

Мне удалось выровнять клетки у начала координат. Последняя клетка по ОХ и ОУ  получилась
чуть больше, чем остальные. (так как использую QGraphicsScene линии образующие эту
клетку рисуются первыми). Немного съехали надписи на ОХ из-за перерисовки линий.

Написал свой класс QGraphicsPointItem, который позволяет добавлять точки (пока квадратные)
на сцену и загнал в цикл свою функцию, график которой мне надо построить. (Не пугайтесь
сильно, она очень страшная).

Вот что вышло



Вот мой класс

 #ifndef QGRAPHICSPOINTITEM_H
 #define QGRAPHICSPOINTITEM_H

 #include 
 class QGraphicsPointItem : public QAbstractGraphicsShapeItem
 {
 QRectF boundingRect() const
 {
    qreal penHalfWidth = this->pen().widthF() / 2;
    return QRectF(  -penHalfWidth, -penHalfWidth,
                    penHalfWidth, penHalfWidth);
}

void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, 
QWidget *widget)
{
    painter->setPen(QPen(Qt::blue, 5));
    painter->setBrush(this->brush());
    painter->drawPoint(0, 0);
}
};
#endif


Вот как добавил точки на сцену:

// График
for (int i = 0; i<10000;i++){
    QGraphicsItem *pointongraphic = new QGraphicsPointItem();
    pointongraphic->setPos(QPointF(2*n +xmin+5*n*i,(BorderRect.height()-((exp((2*sqrt(xmin+2*n*i))/(5*a))*(sin(pow
(xmin+2*n*i,2)/3)*pow(atan(pow((xmin+2*n*i),(1.0/5))/4),(1.0/(bmin+db)))))))));
                   //((exp((2*sqrt(xmin+dx*i))/(5*a))*(sin(pow (xmin+dx*i,2)/3)*pow(atan(pow((xmin+dx*i),(1.0/5))/4),(1.0/(bmin+db)))))));
    graphicsScene->addItem(pointongraphic);


И скрин самой функции на всякий, вдруг кто-то захочет порыться и найдет ошибки в
моей одной строке цикла (простите за этот цикл)



И собственно еще один вопрос: мне бы хотелось расширить мою сцену, так, чтобы дорисовать
точки хотя бы до х = 2.0. Без сетки. Можно ли как-то это сделать?
    


Ответы

Ответ 1



Добавлю свое прямоугольное колесо в этот велосипед. Я определил 2 класса, Chart - рисует график - и Grid - рисует сетку и разметку. Сетка: class Grid : public QGraphicsItem { public: Grid(QGraphicsItem* parent = nullptr); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); // ... сеттеры/геттеры private: qreal m_space; //размер клетки qreal m_scaleX; //масштаб по Ох, для рисования разметки qreal m_scaleY; //масштаб по Оу, для рисования разметки }; Реализация: Grid:: Grid(QGraphicsItem *parent): QGraphicsItem(parent), m_space{30}, m_scaleX{0.5},m_scaleY{0.5} { } QRectF Grid:: boundingRect() const { return scene()->views().first()->rect(); } void Grid:: paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); qreal w = boundingRect().width(); qreal h = boundingRect().height(); qreal start = -m_space*50; //чтобы при изменении масштаба сетка отрисовывалась //рисуем линии по вертикали for(auto chunk = start ; chunk <= w+qAbs(start) ; chunk+=m_space) { painter->save(); painter->setPen(QPen(QBrush(QColor(Qt::gray)), 0.3, Qt::PenStyle::SolidLine)); painter->drawLine(QLineF(chunk, start, chunk, h+qAbs(start))); painter->restore(); } //рисуем линии по горизонтали for(auto chunk = start ; chunk <= h+qAbs(start) ; chunk+=m_space) { painter->save(); painter->setPen(QPen(QBrush(QColor(Qt::gray)), 0.3, Qt::PenStyle::SolidLine)); painter->drawLine(QLineF(start, chunk, w+qAbs(start), chunk)); painter->restore(); } painter->save(); //меняем начало координат painter->translate(m_space, (int)(h/m_space-1)*m_space); //Рисуем оси Оx и Оy painter->drawLine(QLineF(0,0, 0,-h)); painter->drawLine(QLineF(0,0, w, 0)); painter->drawText(-10,10, QString::number(0)); //Рисуем разметку для осей Оx и Оy qreal scX = m_scaleX; for(auto chunk = m_space ; chunk <= w ; chunk+=m_space, scX+=m_scaleX) { painter->drawLine(chunk,-1, static_cast(chunk),1); painter->drawText(chunk-7, 10, QString::number(scX, 'g', 3)); } qreal scY = m_scaleY; for(auto chunk = -m_space ; chunk >= -w ; chunk-=m_space, scY+=m_scaleY) { painter->drawLine(-1, chunk,1, static_cast(chunk)); painter->drawText(-23, chunk, QString::number(scY, 'g', 3)); } painter->restore(); } График: class Chart : public QGraphicsItem { public: Chart(QGraphicsItem* parent = nullptr); QRectF boundingRect() const; void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); //... сеттеры/геттеры protected: qreal f_x(qreal x) const; //реализация функции qreal scaleX(qreal x) const; //масштабирование относительно клетки по Ох qreal scaleY(qreal y) const; //масштабирование относительно клетки по Оу private: qreal m_a; //параметр а qreal m_b; //параметр b qreal m_space; //размер клетки, для масштабирования qreal m_scaleX; //масштаб по Ох, для масштабирования qreal m_scaleY; //масштаб по Оу, для масштабирования }; И реализация Chart:: Chart(QGraphicsItem* parent): QGraphicsItem(parent), m_a{5},m_b{200}, m_space{30}, m_scaleX{0.5},m_scaleY{0.5} { } QRectF Chart:: boundingRect() const { return scene()->views().first()->rect(); } void Chart:: paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) { Q_UNUSED(option); Q_UNUSED(widget); painter->save(); //меняем точку начала координат painter->translate(m_space, (int)(boundingRect().height()/m_space-1)*m_space); //ширина и цвет линии графика painter->setPen(QPen(QColor(Qt::red), 0.7)); //размечаем точки для графика QPainterPath path(QPointF(0.0, 0.0)); for(qreal x = 0.0 ; x < 15 ; x+=0.05) { path.lineTo(scaleX(x), scaleY(f_x(x)) ); } //полупрозрачная закраска графика painter->setBrush(QBrush(QColor(128,128,0,128))); painter->drawPath(path); painter->restore(); } qreal Chart:: f_x(qreal x) const { return qExp(-2*qSqrt(x)/(5*m_a)) * qSin(qPow(x,2.0)/3) * (qAtan(-qPow(qPow(x,0.2)/4, 1/m_b)) + M_PI_2); } qreal Chart:: scaleX(qreal x) const { return m_space * x / m_scaleX; } qreal Chart:: scaleY(qreal y) const { return m_space * y / m_scaleY; } На главном окне переопределяем виртуальную функцию eventFilter для масштабирования сцены при прокрутке колёсика мышки: bool MainWindow:: eventFilter(QObject *watched, QEvent *event) { if(watched->objectName() == "scene") { if(event->type() == QEvent::GraphicsSceneWheel) { QGraphicsSceneWheelEvent* wevent = static_cast(event); //изменяем масштаб ui->gv->scale(wevent->delta() < 0 ? 0.9 : 1.1, wevent->delta() < 0 ? 0.9 : 1.1); //центрируем в точке позиции мыши на сцене if(wevent->delta() < 0) ui->gv->centerOn(wevent->scenePos()); scene.update(); event->accept(); return true; } } return false; } ну и в конструкторе главного окна добавить scene.setObjectName("scene"); //scene объявлен в MainWindow ui->gv->setScene(&scene); //QGraphicsView на ui Grid* grid = new Grid; Chart* chart = new Chart; scene.addItem(grid); scene.addItem(chart); // устанавливаем фильтр событий для перехвата событий колёсика scene.installEventFilter(this); //изменение значений из ui connect(ui->scaleX, &QLineEdit::textChanged, [=]() { bool ok = true; chart->setScaleX(ui->x->text().toDouble(&ok)); grid->setScaleX(ui->y->text().toDouble(&ok)); Q_ASSERT(ok); scene.update(); }); //... для a, b, scaleY, ... Получилось примерно следующее:

Ответ 2



Вы просто не с того конца строите линии сетки. Надо идти от осей вправо и вверх, соответвенно. В качестве тренировки это, безусловно, хорошо создавать свой велосипед, но я все-таки, когда вам надоест, порекомендую, внешнюю к Qt, либу работы с разными графиками Qwt. Вот ее официальный сайт А тут легкое введение на хабре А то знаете, вы только с сеткой занялись, а уже такие проблемы. Оно вам надо? )

Ответ 3



Есть способ проще. Хотя и сомнительный. Переопределить либо в QGraphicsScene либо QGraphicsView метод drawBackground. Фон нарисовать отдельно, и в случае чего делать ему resize. При вашем подходе, если линий станет достаточно много, скорость упадет заметно. QImage* background = new QImage("путь_до_изображения"); void GraphicsScene::drawBackground(QPainter *painter, const QRectF &) { for(int x =0 ; x < height(); x+=background->size().height()) for(int y=0; y < width(); y+=background->size().width()) { painter->drawImage( x,y, *background ); } } В этом примере background заполняет всю сцену своими копиями. Масштаб меняется при помощи метода scale, класса QGraphicsView. Количество клеток путем, увеличения сцены. setSceneRect(QRectF); Изменения стиля, путем замены изображения бэкграунда. А сохранить можно так: QImage image(scene->width(), scene->height(),QImage::Format_ARGB32_Premultiplied); QPainter painter(&image); scene->render(&painter); image.save("/somepath/result.png"); Вот что получилось. https://github.com/NikitaDotIvanov64/stackoverflow

Ответ 4



Вычислите размеры прямоугольника который впишется в область просмотра, и разлиновывайте уже его. А вообще QGraphicScene так не насилуют, слишком графично. Нужно создать компоненты осей, надписей, сетки и линий. Все эти addRect() и addLine() создают визуальные компоненты, способные реагировать на события и поведения других элементов.

понедельник, 15 июля 2019 г.

Помогите правильно построить график Google Chart + nodejs

Здравствуйте, необходимо передать массив с сервера(nodejs) на клиент, чтобы потом по нему строить график. Я передаю массив, но на клиенте пишет, что это не массив. Где ошибка в коде?
Сервер:
app.post('/averageTimeInQueue', function(req, res, next) { var data = [ [2012, 1000, 400, 232], [2005, 1170, 460, 421], [2006, 660, 1120, 4324] ]; res.send(data); });
Клиент:
google.charts.load('current', {'packages':['line']}); google.charts.setOnLoadCallback(drawChart);
function drawChart() { var data = new google.visualization.DataTable(); data.addColumn('number', 'Day'); data.addColumn('number', 'Guardians of the Galaxy'); data.addColumn('number', 'The Avengers'); data.addColumn('number', 'Transformers: Age of Extinction');
data.addRows(averageTimeInQueue); var options = { chart: { title: 'Box Office Earnings in First Two Weeks of Opening', subtitle: 'in millions of dollars (USD)' }, width: 600, height: 350, axes: { x: { 0: {side: 'top'} } } };
var chart = new google.charts.Line(document.getElementById('chart_div2'));
chart.draw(data, options); }
function averageTimeInQueue(){ var jsonData = $.ajax({ url: "/averageTimeInQueue", async: false, type: 'POST' }).responseText; return jsonData; }


Ответ

Конечно не массив, вы же его как текст отправляете. Сериализируйте его в json
на сервере res.send(JSON.stringify(data));
на клиенте data.addRows(averageTimeInQueue()) вместо data.addRows(averageTimeInQueue) и
var jsonData = $.ajax({ url: "/averageTimeInQueue", dataType: "json", async: false, type: 'POST' }).responseText; return JSON.parse(jsonData);

суббота, 13 июля 2019 г.

Нахождение корней уравнения методом дихотомии Java

Столкнулся с небольшой проблемой: (краткая формулировка вопроса дана в самом конце) у меня имеется функция, например, такая: (N = 1 для этого варианта) Их много разных, и все они такие "красивые". График у неё ещё красивее: Так вот, мне необходимо все точки пересечения графика с осью абсцисс (корни уравнения) выделить цветом, и найти эти корни методом дихотомии. Сам алгоритм сложностей не вызвал:
while (right - left > epsilon){ tmp = (right - left)/2;
if (get_Y_for_X(right) * get_Y_for_X(tmp) < 0) { left = tmp; } else { right = tmp; }
root = (left + right)/2; }
Однако, мне нужно проделать это многократно, и найти каждый корень. Как я понимаю, с помощью данного алгоритма можно найти только один корень в заданном промежутке [left, right]. Значит, мне нужно знать все промежутки, в которых находятся корни, и уже в них искать? В общем, я не очень понимаю, как подойти к решению. Буду рад помощи. Возможно, я не увидел какого-то элементарного момента или не додумался до чего-то простого.

Думал следующим образом: раз с помощью алгоритма, написанного сверху, можно найти корень на заданном промежутке (в задании конкретно для этой функции у меня указан промежуток [-4, 4] и epsilon = 0.0001) то я могу разбить его на много промежутков, например, длиной в l = 1 или l = 0.5, и на каждом найти эти корни, записать их и потом уже отметить на графике. То есть, добавлялся еще один цикл while сверх того алгоритма, и выполнялся он длина промежутка / l раз, и затем left = предыдущий right, right = предыдущий right + l, в общем, тут всё предельно просто, однако, опять же загвоздка в том, что корней на этих промежутках может быть гораздо больше одного, а может и не быть вообще. Ведь мне нужно не просто реализовать метод дихотомии, а найти все корни этим методом. К тому же, один пункт в задании меня немного озадачил: нужно будет, также, найти интеграл на промежутке от 2 до 3 корня на графике. Посмотрев на получившийся график, я так и не понял, откуда вести отсчёт, от левой границы или от нуля, и какой корень считать первым, чтобы найти второй и третий. В любом случае, получается не очень хорошо. В указаниях к заданию есть пример сделанной программы (крайне убогий), и, судя по графику, который с помощью неё нарисован, там была использована далеко не такая функция, какая дана в задании, и составители заданий не позаботились об этом. Либо, опять же, я где-то в начале не учёл что-то и зря ищу виноватых.

Для тех, кто напишет "оченьмногобукв", или как-то по-иному возмутится насчёт чрезмерно длинной формулировки вопроса: я всегда стараюсь как можно подробнее поставить вопрос, чтобы тем, кто захочет мне ответить, было всё понятно сразу, а также, стараюсь осветить все стороны своего вопроса. Но, всё же, сделаю ещё так:
Выше дана моя функция, мне нужно методом дихотомии найти все корни этого уравнения на промежутке [-4, 4] с точностью до 0.0001. То есть, мне нужны Х и Y всех точек, которые будут корнями уравнения. Нуждаюсь в помощи с реализацией алгоритма по нахождению этих корней.


Ответ

Проблему отделения корней в данном случае решает подстановка
t = x4 sign(x), x = |t|1/4 sign(t),
вид функции z(t) = y(x(t)) приведён в скриншоте программы MathCAD
(интервал первого графика x = [ - 41/4, 41/4]):

Экстремумы функции f(t) = sin 16t достигаются в точках
Ti = (2i+1)*Pi/32
и хорошо отделяют корни функции z(t).
Анализ значений экстремумов (таблица в скриншоте) с учётом равенства z(0)=1 показывает, что на интервале (0, 1.9) z(t)>0, т.е. корней нет.
Следует учесть, что при x = [-4,4] t = [-256, 256].

воскресенье, 7 июля 2019 г.

Интерактивные Графики в Python: как реализовать аналог функции Manipulate из Mathematica

Добрый день! Недавно начал изучать Python, решая задачу по численным методам. Хотел узнать, можно ли как-то в Python реализовать аналог функции Manipulate как в Mathematica, чтобы была возможность варьировать данные, чтобы это было видно на графике. Привел скрин ниже:

Буду рад любой помощи и подсказке. Спасибо!


Ответ

Можно использовать ipywidgets.interact (чтобы ползунки/график появились, ячейку возможно пару раз исполнить нужно)
import matplotlib.pyplot as plt import numpy as np from ipywidgets import interact
def f(a, k): x = np.arange(11) plt.plot(x, x**k - 1) plt.plot(x, a * (x - 1))
interact(f, a=(0,5), k=(0,6))

Можно записать этот код, используя синтаксис для аннотаций и декоратора:
@interact def f(a: (0,5), k: (0,6)): x = np.arange(11) plt.plot(x, x**k - 1) plt.plot(x, a * (x - 1))

среда, 24 апреля 2019 г.

Метод реализации графического интерфейса


Необходимо будет сделать подобную вещь в своей программе на c# Windows Forms, возможно и WPF. Из чего лучше всего сделать такой график? На нем нужно будет и многое другое вырисовывать, но главное это основные свечи(красные, зеленые). Как мысль, самая банальная, сделать координаты и рисовать по ним прямоугольники с линиями сверху и снизу. А при масштабировании вырисовывать другие, более мелкие или большие. Но, может быть, есть более лаконичное решение данной задачи?


Ответ

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

Подчеркну, что кроме цвета фона использовались настройки по умолчанию, так как не ставил перед собой цели добиться соответствия с приведенным изображением.
Данные получены случайным образом, по примеру из репозитория.
Не буду копировать оттуда пример, но переведу его реализацию на F# для более наглядной демонстрации типов и методов библиотеки
let candleStickSeries() = let model = PlotModel(Title = "", LegendSymbolLength = 24.0 ) let s1 = new CandleStickSeries(Title = "", Color = OxyColors.Black) let r = Random()
Seq.initInfinite (fun _ -> r.NextDouble()) |> Seq.scan(fun price a -> price + a + 0.1) 100.0 |> Seq.indexed |> Seq.map (fun (i, price) -> let high = price + 10.0 + (r.NextDouble() * 10.0) let low = price - (10.0 + (r.NextDouble() * 10.0)) let open' = low + (r.NextDouble() * (high - low)) let close = low + (r.NextDouble() * (high - low)) new HighLowItem(float i, high, low, open', close)) |> Seq.take 30 |> Seq.iter s1.Items.Add
model.Series.Add(s1) model.Axes.Add(new LinearAxis(Position = AxisPosition.Left, MaximumPadding = 0.3, MinimumPadding = 0.3 )) model.Axes.Add(new LinearAxis(Position = AxisPosition.Bottom, MaximumPadding = 0.03, MinimumPadding = 0.03 ))
model
Если хотите добиться полного (или почти полного совпадения), то советую разбить вопросы на несколько небольших и задать их по метке выбранной библиотеки.

среда, 13 марта 2019 г.

Python matplotlib Построение гиперболы

Добрый день! Хочу при помощи matplotlib построить, например, гиперболу. Есть следующий код:
import matplotlib.pyplot as plt import pylab, math xmin = -200 xmax = 200 dx = 0.1
xlist = [float(x) for x in range(xmin,xmax)] ylist = [float(1/x) for x in range(xmin,xmax)]
ax = plt.gca() ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.xaxis.set_ticks_position('bottom') ax.spines['bottom'].set_position(('data',0)) ax.yaxis.set_ticks_position('left') ax.spines['left'].set_position(('data',0)) plt.grid(True) plt.title('График функции ') pylab.plot(xlist,ylist) pylab.savefig('123.png')
Пример работы на картинке Как видно, между двумя ветвями функции есть отрезок. Я знаю, что это связанно с тем, что есть значение крайних точек ветвей, а плот их соединяет. Но это мне не нужно, мне нужно получить нормальный график. Если бы этот график был всегда гиперболой, было бы нормально. Но этим графиком может быть любой график с разрывом. Как избежать этого отрезка? Видел способы, но там использовались дополнительные пакеты(numpy), я не хочу тянуть их в этот код []


Ответ

Для начала повторюсь, что matplotlib уже внутри себя использует numpy, так что избежать его не выйдет. Тем не менее, вот первая версия без numpy в основном коде:
import matplotlib.pyplot as plt import decimal
# Это замена np.arange def arange(start, stop, step): while start < stop: yield start start += decimal.Decimal(step)
hyperbola = lambda x: 1 / x
def asymptote_checker(argument, function): try: function(argument) return True except ZeroDivisionError: return False
xmin = -20 xmax = 20 dx = 0.1
xlist = [round(x, 4) for x in arange(xmin, xmax, dx)]
ylist = [hyperbola(x) if asymptote_checker(x, hyperbola) else float('nan') for x in xlist]
plt.plot(xlist, ylist) plt.show()
С numpy выйдет покороче:
import matplotlib.pyplot as plt import decimal import numpy as np
xmin = -20 xmax = 20 dx = 0.1
xlist = np.around(np.arange(xmin, xmax, dx), decimals=4)
ylist = 1 / xlist
plt.plot(xlist, ylist) plt.show()
Пара общих важных моментов для обеих версий: числа в xlist вместо нуля могут внезапно превратиться в мусор типа 7.0485345e-13 или типа того, что выльется в огромное значение по оси Oy. Второй момент - matplotlib игнорирует (и не соединяет точки) числа типа +inf, -inf, NaN - их можно пометить руками, доверить это numpy или использовать numpy masked array

пятница, 1 февраля 2019 г.

Построить график c#

Добрый день, подскажите пожалуйста, как построить график многочлена : сам многочлен p(x)=An*X^n + An-1*X^n-1+...+A1X+A0
int[] array= new int[10]; int i, num, power; float x;
num=4; x=1;
array[0] = 3; array[1] = -5; array[2] = 6; array[3] = 8; array[4] = -9;
power = num;
double k = 0;
for (i = 0; i <= num; i++) { k += Math.Pow(x, power--) * array[i]; // richTextBox1.AppendText(Convert.ToString(k) +"
");
}
как щас построить график ?


Ответ

Для начала вам будет достаточно стандартного класса Chart, хотя есть и сторонние компоненты для построения красивых графиков, но мне кажется, что сначала лучше разобраться со стандартным контролом. В документации на MSDN есть довольно подробный Tutorial. Основные моменты покажу в коде, подробности в официальной документации.
class ChartForm : Form { public ChartForm() { //создаем элемент Chart Chart myChart = new Chart(); //кладем его на форму и растягиваем на все окно. myChart.Parent = this; myChart.Dock = DockStyle.Fill; //добавляем в Chart область для рисования графиков, их может быть //много, поэтому даем ей имя. myChart.ChartAreas.Add(new ChartArea("Math functions")); //Создаем и настраиваем набор точек для рисования графика, в том //не забыв указать имя области на которой хотим отобразить этот //набор точек. Series mySeriesOfPoint = new Series("Sinus"); mySeriesOfPoint.ChartType = SeriesChartType.Line; mySeriesOfPoint.ChartArea = "Math functions"; for (double x = -Math.PI; x <= Math.PI; x += Math.PI / 10.0) { mySeriesOfPoint.Points.AddXY(x, Math.Sin(x)); } //Добавляем созданный набор точек в Chart myChart.Series.Add(mySeriesOfPoint); } }
Вот собственно минимум кода для рисования графика на форме. Здесь не приведены ни настройки осей координат и сетки, ни другие графические рюшечки которые поддерживает данный контрол, т.к. примеры применения практически всех возможностей этого контрола есть в официальной документации, ссылка выше.
Дополнение:
Вам нужно вычисление многочлена вынести в отдельную функцию. Это можно сделать например так
double Polynom(double x, double[] coefficients) { double y = 0.0; double currentX = 1.0; for(int i = 0; iИ подставить ее вместо Math.Sin в моем примере.