# Help with Math Plot, Graph, Curve

### 问题

• I would like to make a graph drawer but I have no idea where to start from, so if anyone could recommend a method or seen a tutorial or found a project, I would really like to see. I would prefere to be in vb language.

Thanks

2010年7月28日 14:36

### 全部回复

• Hello Dim131,

Sorry for the dalay. Check the following examples which about how to create chart or graph in VB.NET. Hope them helpful.

http://www.linglom.com/2010/05/11/creating-graph-with-vb-net-part-1-basic-chart/
(Creating Graph with VB.NET)
http://msdn.microsoft.com/en-us/beginner/bb308769.aspx
(Generate Charts and Graphs Using Visual Studio Express)

Best regards,

Liliane

Please mark the replies as answers if they help and unmark them if they provide no help.
Welcome to the All-In-One Code Framework! If you have any feedback, please tell us. Thanks

2010年8月3日 6:41
• Thanks for your help, but what I was looking for wasn't exactly that. I am looking for how I can enter a mathematical expression (with an x value) and the programme can plot it in the cartesian coordinates system

thanks,
Dimitris
• 已建议为答案 2011年12月26日 12:30
• 取消建议作为答案 2011年12月26日 12:30
2010年9月3日 18:51
• I am sorry if this does not belong here I dont usally write just read. Dim131 I am having the same issues i am also very determined to find out how to plot points and I hope lines from my app that calculates slope intercept. If you do find a solution or have already please help me I will return the favor.
2011年3月5日 0:53
• One way I have over come this problem is by working out all the possible "y" values if the graph comes in the form of "y=mx+c" at small intervals of of "x." This "small" interval of x will depend on your screen resolution and how accurate you the the graph to be. After this create an array of x values and y values. The y values will be generated by solving the equation of "y=mx+c." After this have a loop to "plot" the graph for you for each point within certain limit. This limit will depend on yours or the user's screen resolution.

Please feel free to email me at: argha_sarkar1994@yahoo.co.in or you can visit my youtube channel on lionking422 or my website at: sagga.co.uk.

2011年12月26日 12:34
• Hi,

Tell us if this code and explanation helps you.

When the program starts, it draws grid lines for the graph. When the user clicks the Graph button, the program checks the m_GraphThread object to see if the graphing thread is running. If m_GraphThread is Nothing, then the program creates the new thread, making its startup routine the DrawGraph subroutine. It sets the thread's priority to BelowNormal so it won't preempt the main program and starts the thread.

If the m_GraphThread object is not Nothing, then the program stops the thread.

' Start drawing the graph.
Private Sub btnGraph_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGraph.Click
' The thread isn't running. Start it.

btnGraph.Text = "Stop"
Else
' The thread is running. Stop it.

btnGraph.Text = "Start"
End If
End Sub

 When the new thread starts, it runs subroutine DrawGraph. This routine repeatedly calls subroutine NewValue to generate a value and PlotValue to plot the value. When the user clicks the Start button, the program aborts the thread and the thread's DrawGraph code catches an exception.

' Draw a graph until stopped.
Private Sub DrawGraph()
Try
' Generate pseudo-random values.
Dim y As Integer = m_Y
Do
' Generate the next value.
NewValue()

' Plot the new value.
PlotValue(y, m_Y)
y = m_Y
Loop
Catch ex As Exception
End Try
End Sub

 Subroutine NewValue generates a random new value in a straightforward manner.

' Generate the next value.
Private Sub NewValue()
' Delay a bit before calculating the value.
Dim stop_time As Date = Now.AddMilliseconds(20)
Do While Now < stop_time
Loop

' Calculate the next value.
Static rnd As New Random
m_Y += rnd.Next(-4, 5)
If m_Y < 0 Then m_Y = 0
If m_Y >= picGraph.ClientSize.Height - 1 Then m_Y = _
picGraph.ClientSize.Height - 1
End Sub
`This is where you can write equation and mathematical stuffs to calculate values

 Subroutine PlotValue is a bit odd. It cannot directly access the program's main form because controls (including the form) can only be modified by the thread that created them. PlotValue starts by checking the InvokeRequired property. If InvokeRequired is True, then the code is running on the thread so it must invoke the main UI thread. In that case, the code makes an array of parameters to pass to the main UI thread and invokes the main thread's PlotValue method. At this point, the main UI thread executes PlotValue. This time InvokeRequired returns False because we're running on the main UI thread. The program uses the Graphics object's DrawImage method to move the existing graph one pixel to the left and then draws the new value.
' Plot a new value.
Private Delegate Sub PlotValueDelegate(ByVal old_y As _
Integer, ByVal new_y As Integer)
Private Sub PlotValue(ByVal old_y As Integer, ByVal new_y _
As Integer)
' See if we're on the worker thread and thus
' need to invoke the main UI thread.
If Me.InvokeRequired Then
' Make arguments for the delegate.
Dim args As Object() = {old_y, new_y}

' Make the delegate.
Dim plot_value_delegate As PlotValueDelegate

' Invoke the delegate on the main UI thread.
Me.Invoke(plot_value_delegate, args)

' We're done.
Exit Sub
End If

' Make the Bitmap and Graphics objects.
Dim wid As Integer = picGraph.ClientSize.Width
Dim hgt As Integer = picGraph.ClientSize.Height
Dim bm As New Bitmap(wid, hgt)
Dim gr As Graphics = Graphics.FromImage(bm)

' Move the old data one pixel to the left.
gr.DrawImage(picGraph.Image, -1, 0)

' Erase the right edge and draw guide lines.
gr.DrawLine(Pens.Blue, wid - 1, 0, wid - 1, hgt - 1)
For i As Integer = m_Ymid To picGraph.ClientSize.Height _
Step GRID_STEP
gr.DrawLine(Pens.LightBlue, wid - 2, i, wid - 1, i)
Next i
For i As Integer = m_Ymid To 0 Step -GRID_STEP
gr.DrawLine(Pens.LightBlue, wid - 2, i, wid - 1, i)
Next i

' Plot a new pixel.
gr.DrawLine(Pens.White, wid - 2, old_y, wid - 1, new_y)

' Display the result.
picGraph.Image = bm
picGraph.Refresh()

gr.Dispose()
End Sub

This program's AddStatus subroutine adds a status message to the txtStatus TextBox. Because the TextBox was created by the main UI thread, the program must check InvokeRequired as before.

' Add a status string to txtStatus.
Private Delegate Sub AddStatusDelegate(ByVal txt As String)
Private Sub AddStatus(ByVal txt As String)
' See if we're on the worker thread and thus
' need to invoke the main UI thread.
If Me.InvokeRequired Then
' Make arguments for the delegate.
Dim args As Object() = {txt}

' Make the delegate.

' Invoke the delegate on the main UI thread.

' We're done.
Exit Sub
End If

txtStatus.Text &= vbCrLf & txt
txtStatus.Select(txtStatus.Text.Length, 0)
txtStatus.ScrollToCaret()
End Sub

Notes: This example uses a Timer to update a label holding the current time.
Because the graphing is performed on a separate thread, the Timer continues to
operate while graphing is occurring. This example is a bit tedious to understand but here is it... Try this and you will succeed...!!

Thanks

Rehan Bharucha - The Tech Robot

MCTS, MCITP, MCPD, MCT

2011年12月26日 13:43
• Hi,

Tell us if this code and explanation helps you.

When the program starts, it draws grid lines for the graph. When the user clicks the Graph button, the program checks the m_GraphThread object to see if the graphing thread is running. If m_GraphThread is Nothing, then the program creates the new thread, making its startup routine the DrawGraph subroutine. It sets the thread's priority to BelowNormal so it won't preempt the main program and starts the thread.

If the m_GraphThread object is not Nothing, then the program stops the thread.

' Start drawing the graph.
Private Sub btnGraph_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGraph.Click
' The thread isn't running. Start it.

btnGraph.Text = "Stop"
Else
' The thread is running. Stop it.

btnGraph.Text = "Start"
End If
End Sub

 When the new thread starts, it runs subroutine DrawGraph. This routine repeatedly calls subroutine NewValue to generate a value and PlotValue to plot the value. When the user clicks the Start button, the program aborts the thread and the thread's DrawGraph code catches an exception.

' Draw a graph until stopped.
Private Sub DrawGraph()
Try
' Generate pseudo-random values.
Dim y As Integer = m_Y
Do
' Generate the next value.
NewValue()

' Plot the new value.
PlotValue(y, m_Y)
y = m_Y
Loop
Catch ex As Exception
End Try
End Sub

 Subroutine NewValue generates a random new value in a straightforward manner.

' Generate the next value.
Private Sub NewValue()
' Delay a bit before calculating the value.
Dim stop_time As Date = Now.AddMilliseconds(20)
Do While Now < stop_time
Loop

' Calculate the next value.
Static rnd As New Random
m_Y += rnd.Next(-4, 5)
If m_Y < 0 Then m_Y = 0
If m_Y >= picGraph.ClientSize.Height - 1 Then m_Y = _
picGraph.ClientSize.Height - 1
End Sub
`This is where you can write equation and mathematical stuffs to calculate values

 Subroutine PlotValue is a bit odd. It cannot directly access the program's main form because controls (including the form) can only be modified by the thread that created them. PlotValue starts by checking the InvokeRequired property. If InvokeRequired is True, then the code is running on the thread so it must invoke the main UI thread. In that case, the code makes an array of parameters to pass to the main UI thread and invokes the main thread's PlotValue method. At this point, the main UI thread executes PlotValue. This time InvokeRequired returns False because we're running on the main UI thread. The program uses the Graphics object's DrawImage method to move the existing graph one pixel to the left and then draws the new value.
' Plot a new value.
Private Delegate Sub PlotValueDelegate(ByVal old_y As _
Integer, ByVal new_y As Integer)
Private Sub PlotValue(ByVal old_y As Integer, ByVal new_y _
As Integer)
' See if we're on the worker thread and thus
' need to invoke the main UI thread.
If Me.InvokeRequired Then
' Make arguments for the delegate.
Dim args As Object() = {old_y, new_y}

' Make the delegate.
Dim plot_value_delegate As PlotValueDelegate

' Invoke the delegate on the main UI thread.
Me.Invoke(plot_value_delegate, args)

' We're done.
Exit Sub
End If

' Make the Bitmap and Graphics objects.
Dim wid As Integer = picGraph.ClientSize.Width
Dim hgt As Integer = picGraph.ClientSize.Height
Dim bm As New Bitmap(wid, hgt)
Dim gr As Graphics = Graphics.FromImage(bm)

' Move the old data one pixel to the left.
gr.DrawImage(picGraph.Image, -1, 0)

' Erase the right edge and draw guide lines.
gr.DrawLine(Pens.Blue, wid - 1, 0, wid - 1, hgt - 1)
For i As Integer = m_Ymid To picGraph.ClientSize.Height _
Step GRID_STEP
gr.DrawLine(Pens.LightBlue, wid - 2, i, wid - 1, i)
Next i
For i As Integer = m_Ymid To 0 Step -GRID_STEP
gr.DrawLine(Pens.LightBlue, wid - 2, i, wid - 1, i)
Next i

' Plot a new pixel.
gr.DrawLine(Pens.White, wid - 2, old_y, wid - 1, new_y)

' Display the result.
picGraph.Image = bm
picGraph.Refresh()

gr.Dispose()
End Sub

This program's AddStatus subroutine adds a status message to the txtStatus TextBox. Because the TextBox was created by the main UI thread, the program must check InvokeRequired as before.

' Add a status string to txtStatus.
Private Delegate Sub AddStatusDelegate(ByVal txt As String)
Private Sub AddStatus(ByVal txt As String)
' See if we're on the worker thread and thus
' need to invoke the main UI thread.
If Me.InvokeRequired Then
' Make arguments for the delegate.
Dim args As Object() = {txt}

' Make the delegate.

' Invoke the delegate on the main UI thread.

' We're done.
Exit Sub
End If

txtStatus.Text &= vbCrLf & txt
txtStatus.Select(txtStatus.Text.Length, 0)
txtStatus.ScrollToCaret()
End Sub

Notes: This example uses a Timer to update a label holding the current time.
Because the graphing is performed on a separate thread, the Timer continues to
operate while graphing is occurring. This example is a bit tedious to understand but here is it... Try this and you will succeed...!!

Thanks

Rehan Bharucha - The Tech Robot

MCTS, MCITP, MCPD, MCT

Hi Sir,

There was a slight mistake in the above code.

First thing, assign a white background picture to the picturebox picgraph

Set the gridstep variable to the desired gap in between the grid lines horrizontal here i have chosen 3

Take up a windows application and copy paste the code with controls button named as btnGraph textbox as txtStatus and picturebox as picGraph, set the form background color as white, picturebox default image to white and run the application after pasting this code entirely without changing the name of the form.

Public Class Form1
Private m_Y As Integer

End Sub

' Start drawing the graph.
Private Sub btnGraph_Click(sender As System.Object, e As System.EventArgs) Handles btnGraph.Click
' The thread isn't running. Start it.

btnGraph.Text = "Stop"
Else
' The thread is running. Stop it.

btnGraph.Text = "Start"
End If

End Sub

' Draw a graph until stopped.
Private Sub DrawGraph()
Try
' Generate pseudo-random values.
Dim y As Integer = m_Y
Do
' Generate the next value.
NewValue()

' Plot the new value.
PlotValue(y, m_Y)
y = m_Y
Loop
Catch ex As Exception
End Try
End Sub

' Generate the next value.
Private Sub NewValue()
' Delay a bit before calculating the value.
Dim stop_time As Date = Now.AddMilliseconds(20)
Do While Now < stop_time
Loop

' Calculate the next value.
Static rnd As New Random
m_Y = rnd.Next(10, 100)
If m_Y < 0 Then m_Y = 0
If m_Y >= picGraph.ClientSize.Height - 1 Then m_Y = _
picGraph.ClientSize.Height - 1
End Sub

Private Delegate Sub PlotValueDelegate(ByVal old_y As Integer, ByVal new_y As Integer)

Private Sub PlotValue(ByVal old_y As Integer, ByVal new_y As Integer)
' See if we're on the worker thread and thus
' need to invoke the main UI thread.
If Me.InvokeRequired Then
' Make arguments for the delegate.
Dim args As Object() = {old_y, new_y}

' Make the delegate.
Dim plot_value_delegate As PlotValueDelegate

' Invoke the delegate on the main UI thread.
Me.Invoke(plot_value_delegate, args)

' We're done.
Exit Sub
End If

' Make the Bitmap and Graphics objects.
Dim wid As Integer = picGraph.ClientSize.Width
Dim hgt As Integer = picGraph.ClientSize.Height
Dim bm As New Bitmap(wid, hgt)
Dim gr As Graphics = Graphics.FromImage(bm)
Dim m_Ymid As Integer
Dim GRID_STEP As Integer = 10
'Top left corner is considered as 0

' Move the old data one pixel to the left.
gr.DrawImage(picGraph.Image, -1, 0)

' Erase the right edge and draw guide lines.
gr.DrawLine(Pens.Blue, wid - 1, 0, wid - 1, hgt - 1)
For i As Integer = m_Ymid To picGraph.ClientSize.Height Step GRID_STEP
gr.DrawLine(Pens.LightBlue, wid - 2, i, wid - 1, i)
Next i
For i As Integer = m_Ymid To 0 Step -GRID_STEP
gr.DrawLine(Pens.LightBlue, wid - 2, i, wid - 1, i)
Next i

' Plot a new pixel.
gr.DrawLine(Pens.White, wid - 2, old_y, wid - 1, new_y)

' Display the result.
picGraph.Image = bm
picGraph.Refresh()

gr.Dispose()
End Sub

' Add a status string to txtStatus.
Private Delegate Sub AddStatusDelegate(ByVal txt As String)
Private Sub AddStatus(ByVal txt As String)
' See if we're on the worker thread and thus
' need to invoke the main UI thread.
If Me.InvokeRequired Then
' Make arguments for the delegate.
Dim args As Object() = {txt}

' Make the delegate.

' Invoke the delegate on the main UI thread.

' We're done.
Exit Sub
End If

txtStatus.Text &= vbCrLf & txt
txtStatus.Select(txtStatus.Text.Length, 0)
txtStatus.ScrollToCaret()
End Sub

End Class

This application when run produces the result by automated plotting of graph based on random values in the function NewValue where you can also put equation to calculate value for your Y axis (Your logic comes in this function).

The below image is when the application is run, the graph comes plotting from right side of screen scrolling towards the left of the screen, just like a eco cardiogram of a heart patient based on random values.

This is it!

I hope this might have solved a bit of your concern. Dont forget to upvote it and mark as answer if it helps you even a bit..

Thanks

Rehan Bharucha - The Tech Robot

MCTS, MCITP, MCPD, MCT

2011年12月28日 15:43